//
// 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());
}