Jad*_*ias 134 .net c# linq ienumerable indexof
我写了这个:
public static class EnumerableExtensions
{
public static int IndexOf<T>(this IEnumerable<T> obj, T value)
{
return obj
.Select((a, i) => (a.Equals(value)) ? i : -1)
.Max();
}
public static int IndexOf<T>(this IEnumerable<T> obj, T value
, IEqualityComparer<T> comparer)
{
return obj
.Select((a, i) => (comparer.Equals(a, value)) ? i : -1)
.Max();
}
}
Run Code Online (Sandbox Code Playgroud)
但我不知道它是否已经存在,是吗?
Mar*_*ell 115
我会质疑智慧,但也许:
source.TakeWhile(x => x != value).Count();
Run Code Online (Sandbox Code Playgroud)
(如果需要,可以使用EqualityComparer<T>.Default模拟!=) - 但如果没有找到,你需要注意返回-1 ...所以也许只是做很长的路
public static int IndexOf<T>(this IEnumerable<T> source, T value)
{
int index = 0;
var comparer = EqualityComparer<T>.Default; // or pass in as a parameter
foreach (T item in source)
{
if (comparer.Equals(item, value)) return index;
index++;
}
return -1;
}
Run Code Online (Sandbox Code Playgroud)
Sco*_*man 48
以IEnumerable为出发点的重点是你可以懒洋洋地迭代内容.因此,没有真正的索引概念.你正在做的事情对于IEnumerable来说真的没有多大意义.如果您需要支持索引访问的内容,请将其放在实际列表或集合中.
dah*_*byk 24
我会像这样实现它:
public static class EnumerableExtensions
{
public static int IndexOf<T>(this IEnumerable<T> obj, T value)
{
return obj.IndexOf(value, null);
}
public static int IndexOf<T>(this IEnumerable<T> obj, T value, IEqualityComparer<T> comparer)
{
comparer = comparer ?? EqualityComparer<T>.Default;
var found = obj
.Select((a, i) => new { a, i })
.FirstOrDefault(x => comparer.Equals(x.a, value));
return found == null ? -1 : found.i;
}
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*tts 14
我现在这样做的方式比已经建议的方式要短一些,据我所知,给出了预期的结果:
var index = haystack.ToList().IndexOf(needle);
Run Code Online (Sandbox Code Playgroud)
它有点笨重,但它完成了工作并且相当简洁.
小智 6
我认为最好的选择是这样实现:
public static int IndexOf<T>(this IEnumerable<T> enumerable, T element, IEqualityComparer<T> comparer = null)
{
int i = 0;
comparer = comparer ?? EqualityComparer<T>.Default;
foreach (var currentElement in enumerable)
{
if (comparer.Equals(currentElement, element))
{
return i;
}
i++;
}
return -1;
}
Run Code Online (Sandbox Code Playgroud)
它也不会创建匿名对象
抓住位置的最佳方法是通过FindIndex此功能仅适用于List<>
例
int id = listMyObject.FindIndex(x => x.Id == 15);
Run Code Online (Sandbox Code Playgroud)
如果您有枚举器或数组,请使用这种方式
int id = myEnumerator.ToList().FindIndex(x => x.Id == 15);
Run Code Online (Sandbox Code Playgroud)
要么
int id = myArray.ToList().FindIndex(x => x.Id == 15);
Run Code Online (Sandbox Code Playgroud)
游戏有点晚了,我知道......但这就是我最近所做的.它与您的略有不同,但允许程序员指定相等操作需要什么(谓词).我发现在处理不同类型时非常有用,因为我有一个通用的方法来做它,无论对象类型和<T>内置的相等运算符.
它还具有非常小的内存占用,并且非常,非常快速/高效...如果你关心它.
更糟糕的是,您只需将其添加到扩展列表中即可.
无论如何......在这里.
public static int IndexOf<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
int retval = -1;
var enumerator = source.GetEnumerator();
while (enumerator.MoveNext())
{
retval += 1;
if (predicate(enumerator.Current))
{
IDisposable disposable = enumerator as System.IDisposable;
if (disposable != null) disposable.Dispose();
return retval;
}
}
IDisposable disposable = enumerator as System.IDisposable;
if (disposable != null) disposable.Dispose();
return -1;
}
Run Code Online (Sandbox Code Playgroud)
希望这有助于某人.
几年后,但这使用Linq,如果找不到则返回-1,不创建额外的对象,并且应该在找到时短路[而不是遍历整个IEnumerable]:
public static int IndexOf<T>(this IEnumerable<T> list, T item)
{
return list.Select((x, index) => EqualityComparer<T>.Default.Equals(item, x)
? index
: -1)
.FirstOr(x => x != -1, -1);
}
Run Code Online (Sandbox Code Playgroud)
'FirstOr'在哪里:
public static T FirstOr<T>(this IEnumerable<T> source, T alternate)
{
return source.DefaultIfEmpty(alternate)
.First();
}
public static T FirstOr<T>(this IEnumerable<T> source, Func<T, bool> predicate, T alternate)
{
return source.Where(predicate)
.FirstOr(alternate);
}
Run Code Online (Sandbox Code Playgroud)