// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // namespace MUnique.OpenMU.GameLogic; /// /// Extensions for . /// public static class EnumerableExtensions { /// /// Executes the for each element of . /// /// The generic type of the enumerable. /// The enumerable. /// The action which should be executed for each element. /// action. public static void ForEach(this IEnumerable enumerable, Action action) { if (action is null) { throw new ArgumentNullException(nameof(action)); } foreach (var item in enumerable) { action(item); } } /// /// Executes the for each element of . /// /// The generic type of the enumerable. /// The enumerable. /// The action which should be executed for each element. /// action. public static async ValueTask ForEachAsync(this IEnumerable enumerable, Func action) { if (action is null) { throw new ArgumentNullException(nameof(action)); } foreach (var item in enumerable) { await action(item).ConfigureAwait(false); } } /// /// Returns the enumerable as list, by either casting it or creating it. /// /// The type of the list elements. /// The enumerable. /// The list. public static IList AsList(this IEnumerable enumerable) { if (enumerable is IList list) { return list; } return enumerable.ToList(); } /// /// Selects a random element of an enumerable. /// /// The generic type of the enumerable. /// The enumerable. /// The randomizer. /// The randomly selected element. public static T? SelectRandom(this IEnumerable enumerable, IRandomizer randomizer) { var list = enumerable as IList ?? enumerable.ToList(); if (list.Count > 0) { var index = randomizer.NextInt(0, list.Count); return list[index]; } return default; } /// /// Selects a random element of an enumerable. /// /// The generic type of the enumerable. /// The enumerable. /// The randomly selected element. public static T? SelectRandom(this IEnumerable enumerable) => SelectRandom(enumerable, Rand.GetRandomizer()); /// /// Selects a random weighted element of an enumerable. /// /// The generic type of the enumerable. /// The enumerable. /// The weights associated with , respectively. /// The randomizer. /// The randomly selected weighted element. public static T? SelectWeightedRandom(this IEnumerable enumerable, IEnumerable weights, IRandomizer randomizer) { var list = enumerable as IList ?? enumerable.ToList(); var weightList = weights as IList ?? weights.ToList(); if (list.Count > 0 && weightList.Count == list.Count) { var roll = randomizer.NextInt(0, weights.Sum()); int inc = 0; for (int i = 0; i < weightList.Count; i++) { inc += weightList[i]; if (roll < inc) { return list[i]; } } return SelectRandom(enumerable, randomizer); // Fallback in case there are no weights assigned (>0) } return default; } /// /// Selects a random weighted element of an enumerable. /// /// The generic type of the enumerable. /// The enumerable. /// The weights associated with , respectively. /// The randomly selected weighted element. public static T? SelectWeightedRandom(this IEnumerable enumerable, IEnumerable weights) => SelectWeightedRandom(enumerable, weights, Rand.GetRandomizer()); }