2021-09-27 12:42:46 +00:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
2022-09-24 21:13:29 +00:00
|
|
|
using System.Reflection.Metadata;
|
2021-10-21 03:18:15 +00:00
|
|
|
using System.Threading.Tasks;
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
namespace Wabbajack.Common;
|
|
|
|
|
|
|
|
public static class IEnumerableExtensions
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
public static void Do<T>(this IEnumerable<T> coll, Action<T> f)
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
foreach (var i in coll) f(i);
|
|
|
|
}
|
2022-09-24 21:13:29 +00:00
|
|
|
|
2021-12-27 16:24:45 +00:00
|
|
|
#region Shuffle
|
2022-09-24 21:13:29 +00:00
|
|
|
|
2021-12-27 16:24:45 +00:00
|
|
|
/// https://stackoverflow.com/questions/5807128/an-extension-method-on-ienumerable-needed-for-shuffling
|
|
|
|
|
|
|
|
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
|
|
|
|
{
|
|
|
|
return source.ShuffleIterator(rng);
|
|
|
|
}
|
|
|
|
|
|
|
|
private static IEnumerable<T> ShuffleIterator<T>(
|
|
|
|
this IEnumerable<T> 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];
|
|
|
|
}
|
|
|
|
}
|
2022-09-24 21:13:29 +00:00
|
|
|
|
2021-12-27 16:24:45 +00:00
|
|
|
#endregion
|
2021-09-27 12:42:46 +00:00
|
|
|
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
public static IEnumerable<TOut> TryKeep<TIn, TOut>(this IEnumerable<TIn> coll, Func<TIn, (bool, TOut)> fn)
|
|
|
|
{
|
|
|
|
return coll.Select(fn).Where(p => p.Item1).Select(p => p.Item2);
|
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> coll)
|
|
|
|
{
|
|
|
|
var rnd = new Random();
|
|
|
|
var data = coll.ToArray();
|
|
|
|
for (var x = 0; x < data.Length; x++)
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
var a = rnd.Next(0, data.Length);
|
|
|
|
var b = rnd.Next(0, data.Length);
|
2021-09-27 12:42:46 +00:00
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
(data[b], data[a]) = (data[a], data[b]);
|
2021-09-27 12:42:46 +00:00
|
|
|
}
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2023-10-12 12:04:38 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Splits the collection into `size` parts
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="coll"></param>
|
|
|
|
/// <param name="count"></param>
|
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
|
/// <returns></returns>
|
|
|
|
public static IEnumerable<IEnumerable<T>> Partition<T>(this IEnumerable<T> coll, int count)
|
2022-09-24 21:13:29 +00:00
|
|
|
{
|
|
|
|
var asList = coll.ToList();
|
|
|
|
|
|
|
|
IEnumerable<T> SkipEnumerable(IList<T> list, int offset, int size)
|
|
|
|
{
|
|
|
|
for (var i = offset; i < list.Count; i += size)
|
|
|
|
{
|
|
|
|
yield return list[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-12 12:04:38 +00:00
|
|
|
return Enumerable.Range(0, count).Select(offset => SkipEnumerable(asList, offset, count));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Split the collection into `size` parts
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="coll"></param>
|
|
|
|
/// <param name="size"></param>
|
|
|
|
/// <typeparam name="T"></typeparam>
|
|
|
|
/// <returns></returns>
|
|
|
|
public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> coll, int size)
|
|
|
|
{
|
|
|
|
List<T> current = new();
|
|
|
|
foreach (var itm in coll)
|
|
|
|
{
|
|
|
|
current.Add(itm);
|
|
|
|
if (current.Count == size)
|
|
|
|
{
|
|
|
|
yield return current;
|
|
|
|
current = new List<T>();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (current.Count > 0)
|
|
|
|
yield return current;
|
2022-09-24 21:13:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-23 16:51:17 +00:00
|
|
|
public static IEnumerable<T> OnEach<T>(this IEnumerable<T> coll, Action<T> fn)
|
|
|
|
{
|
|
|
|
foreach (var itm in coll)
|
2021-09-27 12:42:46 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
fn(itm);
|
|
|
|
yield return itm;
|
2021-09-27 12:42:46 +00:00
|
|
|
}
|
2021-10-23 16:51:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public static async IAsyncEnumerable<T> OnEach<T>(this IEnumerable<T> coll, Func<T, Task> fn)
|
|
|
|
{
|
|
|
|
foreach (var itm in coll)
|
2021-10-21 03:18:15 +00:00
|
|
|
{
|
2021-10-23 16:51:17 +00:00
|
|
|
await fn(itm);
|
|
|
|
yield return itm;
|
2021-10-21 03:18:15 +00:00
|
|
|
}
|
2021-09-27 12:42:46 +00:00
|
|
|
}
|
|
|
|
}
|