@ शिम्मी की प्रतिक्रिया के आधार पर, मैंने एक विस्तार विधि बनाई जो वह समाधान है जो हर कोई चाहता है। यह सरल, उपयोग में आसान है, और केवल एक बार संग्रह के माध्यम से लूप करता है।
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);
}
}
}
}