using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Metadata; using System.Threading.Tasks; namespace Wabbajack.Common; public static class IEnumerableExtensions { public static void Do(this IEnumerable coll, Action f) { foreach (var i in coll) f(i); } #region Shuffle /// https://stackoverflow.com/questions/5807128/an-extension-method-on-ienumerable-needed-for-shuffling public static IEnumerable Shuffle(this IEnumerable source, Random rng) { return source.ShuffleIterator(rng); } private static IEnumerable ShuffleIterator( this IEnumerable source, Random rng) { var buffer = source.ToList(); for (int i = 0; i < buffer.Count; i++) { int j = rng.Next(i, buffer.Count); yield return buffer[j]; buffer[j] = buffer[i]; } } #endregion public static IEnumerable TryKeep(this IEnumerable coll, Func fn) { return coll.Select(fn).Where(p => p.Item1).Select(p => p.Item2); } public static IEnumerable Shuffle(this IEnumerable coll) { var rnd = new Random(); var data = coll.ToArray(); for (var x = 0; x < data.Length; x++) { var a = rnd.Next(0, data.Length); var b = rnd.Next(0, data.Length); (data[b], data[a]) = (data[a], data[b]); } return data; } /// /// Splits the collection into `size` parts /// /// /// /// /// public static IEnumerable> Partition(this IEnumerable coll, int count) { var asList = coll.ToList(); IEnumerable SkipEnumerable(IList list, int offset, int size) { for (var i = offset; i < list.Count; i += size) { yield return list[i]; } } return Enumerable.Range(0, count).Select(offset => SkipEnumerable(asList, offset, count)); } /// /// Split the collection into `size` parts /// /// /// /// /// public static IEnumerable> Batch(this IEnumerable coll, int size) { List current = new(); foreach (var itm in coll) { current.Add(itm); if (current.Count == size) { yield return current; current = new List(); } } if (current.Count > 0) yield return current; } public static IEnumerable OnEach(this IEnumerable coll, Action fn) { foreach (var itm in coll) { fn(itm); yield return itm; } } public static async IAsyncEnumerable OnEach(this IEnumerable coll, Func fn) { foreach (var itm in coll) { await fn(itm); yield return itm; } } }