Цикл Форач, определите, какая последняя итерация цикла

У меня есть цикл форач и мне нужно выполнить некоторую логику, когда последний элемент выбран из списка List, например:

 foreach (Item result in Model.Results)
 {
      //if current result is the last item in Model.Results
      //then do something in the code
 }

Могу ли я узнать, какой цикл является последним без использования для цикла и счетчиков?

216
задан ChrisF 19 September 2011 в 08:34
поделиться

1 ответ

На основе ответа @Shimmy я создал дополнительный метод, который является решением, которое все хотят. Это просто, просто в использовании, и только циклы через набор однажды.

internal static class EnumerableExtensions
{
    public static void ForEachLast<T>(this IEnumerable<T> collection, Action<T>? actionExceptLast = null, Action<T>? actionOnLast = null)
    {
        using var enumerator = collection.GetEnumerator();
        var isNotLast = enumerator.MoveNext();
        while (isNotLast)
        {
            var current = enumerator.Current;
            isNotLast = enumerator.MoveNext();
            var action = isNotLast ? actionExceptLast : actionOnLast;
            action?.Invoke(current);
        }
    }
}

Это работает над любым IEnumerable<T>. Использование похоже на это:

var items = new[] {1, 2, 3, 4, 5};
items.ForEachLast(i => Console.WriteLine($"{i},"), i => Console.WriteLine(i));

Вывод похож:

1,
2,
3,
4,
5

Кроме того, можно превратить это в Select метод стиля. Затем повторное использование, что расширение в ForEach. Тот код похож на это:

internal static class EnumerableExtensions
{
    public static void ForEachLast<T>(this IEnumerable<T> collection, Action<T>? actionExceptLast = null, Action<T>? actionOnLast = null) =>
        // ReSharper disable once IteratorMethodResultIsIgnored
        collection.SelectLast(i => { actionExceptLast?.Invoke(i); return true; }, i => { actionOnLast?.Invoke(i); return true; }).ToArray();

    public static IEnumerable<TResult> SelectLast<T, TResult>(this IEnumerable<T> collection, Func<T, TResult>? selectorExceptLast = null, Func<T, TResult>? selectorOnLast = null)
    {
        using var enumerator = collection.GetEnumerator();
        var isNotLast = enumerator.MoveNext();
        while (isNotLast)
        {
            var current = enumerator.Current;
            isNotLast = enumerator.MoveNext();
            var selector = isNotLast ? selectorExceptLast : selectorOnLast;
            //https://stackoverflow.com/a/32580613/294804
            if (selector != null)
            {
                yield return selector.Invoke(current);
            }
        }
    }
}
0
ответ дан 23 November 2019 в 04:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: