var item = list.Where(t => somecondition);
我希望能够找到返回的元素的索引,事实上,在我的情况下,我想要的只是一个索引,这样我就可以将.Skip()放到列表中了。 / p>
有没有办法在IEnumerable中执行此操作?我讨厌为此使用List<T>
,但确实有FindIndex()
方法
答案 0 :(得分:42)
当然,这很简单:
var index = list.Select((value, index) => new { value, index = index + 1 })
.Where(pair => SomeCondition(pair.value))
.Select(pair => pair.index)
.FirstOrDefault() - 1;
如果找到匹配的内容,则返回索引,否则返回-1。 +1和-1是为了获得没有匹配的情况的行为。如果你知道总会有匹配,那就更简单了:
var index = list.Select((value, index) => new { value, index })
.Where(pair => SomeCondition(pair.value))
.Select(pair => pair.index)
.FirstOrDefault();
如果你很高兴从那时开始获得列表的其余部分,SkipWhile
肯定是你的朋友,正如克里斯所提到的那样。如果想要列表的其余部分和原始索引,那也很容易:
var query = list.Select((value, index) => new { value, index })
.SkipWhile(pair => !SomeCondition(pair.value))
这将为您提供第一个匹配{ value, index }
的值的SomeCondition
对序列。
答案 1 :(得分:37)
如果您真的只需要第一个索引,那么请计算那些不匹配的索引:
var index = list.TakeWhile(t => !someCondition).Count()
答案 2 :(得分:26)
我需要更多上下文,但如果您只是获取索引以便拨打.Skip
,我建议您查看.SkipWhile
。
如果您确实需要索引,我建议您编写自己的.IndexOf
扩展方法。
答案 3 :(得分:17)
当然可以使用IEnumerable ......
public static class EnumerableExtension
{
public static int FirstIndexMatch<TItem>(this IEnumerable<TItem> items, Func<TItem,bool> matchCondition)
{
var index = 0;
foreach (var item in items)
{
if(matchCondition.Invoke(item))
{
return index;
}
index++;
}
return -1;
}
}
答案 4 :(得分:8)
您可以首先使用索引投影列表项:
var item = list.Select((item, index) => new { Item = item, Index = index })
.Where(pair => SomeCondition(pair.Item))
.Select(result => result.Index);
答案 5 :(得分:0)
如果您知道自己有一个列表,而不是IEnumerbale或IQueryable之类的列表,那可能很好...
public static int IndexOf<T>(this IList<T> source, Func<T, bool> condition)
{
for (int i = 0; i < source.Count; i++)
if (condition(source[i]))
return i;
return -1;
}
答案 6 :(得分:0)
关于Jon Skeet的答案,可以在调用FirstOrDefault之前使用DefaultIfEmpty(),而无需在索引中进行加减。
var index = list.Select((value, index) => new { value, index })
.Where(pair => SomeCondition(pair.value))
.Select(pair => pair.index).DefaultIfEmpty(-1)
.FirstOrDefault();