namespace UnityHelpers.Core.Extension { using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using Random; public static class IEnumerableExtensions { private static readonly ConcurrentDictionary ComparerCache = new(); public static LinkedList ToLinkedList(this IEnumerable source) { return new LinkedList(source); } public static IList AsList(this IEnumerable enumeration) { if (enumeration is IList list) { return list; } return enumeration.ToList(); } public static IEnumerable OrderBy( this IEnumerable enumeration, Func comparer ) { FuncBasedComparer comparerObject = (FuncBasedComparer) ComparerCache.GetOrAdd(comparer, () => new FuncBasedComparer(comparer)); return enumeration.OrderBy(_ => _, comparerObject); } public static IEnumerable Ordered(this IEnumerable enumerable) where T : IComparable { return enumerable.OrderBy(_ => _); } public static IEnumerable Shuffled( this IEnumerable enumerable, IRandom random = null ) { random = random ?? ThreadLocalRandom.Instance; return enumerable.OrderBy(_ => random.Next()); } public static IEnumerable Infinite(this IEnumerable enumerable) { ICollection collection = enumerable as ICollection ?? enumerable.ToList(); if (collection.Count == 0) { yield break; } while (true) { foreach (T element in collection) { yield return element; } } } public static void ForEach(this IEnumerable enumerable, Action action) { foreach (T item in enumerable) { action(item); } } public static IEnumerable> Partition(this IEnumerable items, int size) { using var enumerator = items.GetEnumerator(); bool hasNext = enumerator.MoveNext(); IEnumerable NextPartitionOf() { int remainingCountForPartition = size; while (remainingCountForPartition-- > 0 && hasNext) { yield return enumerator.Current; hasNext = enumerator.MoveNext(); } } while (hasNext) { yield return NextPartitionOf().ToList(); } } public static List ToList(this IEnumerable enumerable, int count) { List list = new(count); list.AddRange(enumerable); return list; } private class FuncBasedComparer : IComparer { private readonly Func _comparer; public FuncBasedComparer(Func comparer) { _comparer = comparer ?? throw new ArgumentNullException(nameof(comparer)); } public int Compare(T lhs, T rhs) { return _comparer(lhs, rhs); } } } }