Подтвердить что ты не робот

Поиск первого индекса элемента, который соответствует условию с использованием LINQ

var item = list.Where(t => somecondition);

Мне бы хотелось узнать индекс возвращаемого элемента, на самом деле, в моем случае все, что я хочу, - это индекс, так что я могу .Skip() в списке тем большим количеством.

Есть ли способ сделать это в IEnumerable? Я бы не хотел использовать List<T> для этого, но у него есть метод FindIndex()

4b9b3361

Ответ 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);