using System; using System.Collections.Generic; using System.Linq; namespace Spectre.Console.Internal { internal static class EnumerableExtensions { public static int IndexOf(this IEnumerable source, T item) where T : class { var index = 0; foreach (var candidate in source) { if (candidate == item) { return index; } index++; } return -1; } public static int GetCount(this IEnumerable source) { if (source is IList list) { return list.Count; } if (source is T[] array) { return array.Length; } return source.Count(); } public static void ForEach(this IEnumerable source, Action action) { foreach (var item in source) { action(item); } } public static bool AnyTrue(this IEnumerable source) { return source.Any(b => b); } public static IEnumerable<(int Index, bool First, bool Last, T Item)> Enumerate(this IEnumerable source) { if (source is null) { throw new ArgumentNullException(nameof(source)); } return Enumerate(source.GetEnumerator()); } public static IEnumerable<(int Index, bool First, bool Last, T Item)> Enumerate(this IEnumerator source) { if (source is null) { throw new ArgumentNullException(nameof(source)); } var first = true; var last = !source.MoveNext(); T current; for (var index = 0; !last; index++) { current = source.Current; last = !source.MoveNext(); yield return (index, first, last, current); first = false; } } public static IEnumerable SelectIndex(this IEnumerable source, Func func) { return source.Select((value, index) => func(value, index)); } #if !NET5_0 public static IEnumerable<(TFirst First, TSecond Second)> Zip( this IEnumerable source, IEnumerable first) { return source.Zip(first, (first, second) => (first, second)); } #endif public static IEnumerable<(TFirst First, TSecond Second, TThird Third)> Zip( this IEnumerable first, IEnumerable second, IEnumerable third) { return first.Zip(second, (a, b) => (a, b)) .Zip(third, (a, b) => (a.a, a.b, b)); } } }