Поиск первого индекса элемента, который соответствует условию с использованием LINQ
var item = list.Where(t => somecondition);
Мне бы хотелось узнать индекс возвращаемого элемента, на самом деле, в моем случае все, что я хочу, - это индекс, так что я могу .Skip() в списке тем большим количеством.
Есть ли способ сделать это в IEnumerable? Я бы не хотел использовать List<T>
для этого, но у него есть метод FindIndex()
Ответы
Ответ 1
Мне нужен больше контекста, но если вы просто получите индекс, чтобы вы могли вызвать .Skip
, я бы рекомендовал взглянуть на .SkipWhile
.
Если вам действительно нужен индекс, я бы предложил написать собственный метод расширения .IndexOf
.
Ответ 2
Конечно, это довольно легко:
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
.
Ответ 3
Если вам действительно нужен только первый индекс, то подсчитайте те, которые не соответствуют:
var index = list.TakeWhile(t => !someCondition).Count()
Ответ 4
Конечно, это возможно с помощью 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;
}
}
Ответ 5
Сначала вы можете проецировать элементы списка со своими индексами:
var item = list.Select((item, index) => new { Item = item, Index = index })
.Where(pair => SomeCondition(pair.Item))
.Select(result => result.Index);