Unstable 0.17.0.0
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace Barotrauma.Extensions
|
||||
{
|
||||
@@ -9,69 +10,102 @@ namespace Barotrauma.Extensions
|
||||
/// <summary>
|
||||
/// Randomizes the collection (using OrderBy) and returns it.
|
||||
/// </summary>
|
||||
public static IOrderedEnumerable<T> Randomize<T>(this IEnumerable<T> source, Rand.RandSync randSync = Rand.RandSync.Unsynced)
|
||||
public static T[] Randomize<T>(this IList<T> source, Rand.RandSync randSync = Rand.RandSync.Unsynced)
|
||||
{
|
||||
return source.OrderBy(i => Rand.Value(randSync));
|
||||
return source.OrderBy(i => Rand.Value(randSync)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Randomizes the list in place without creating a new collection, using a Fisher-Yates-based algorithm.
|
||||
/// </summary>
|
||||
public static void Shuffle<T>(this IList<T> list, Rand.RandSync randSync = Rand.RandSync.Unsynced)
|
||||
=> list.Shuffle(Rand.GetRNG(randSync));
|
||||
|
||||
public static void Shuffle<T>(this IList<T> list, Random rng)
|
||||
{
|
||||
int n = list.Count;
|
||||
while (n > 1)
|
||||
{
|
||||
n--;
|
||||
int k = Rand.Int(n + 1, randSync);
|
||||
int k = rng.Next(n + 1);
|
||||
T value = list[k];
|
||||
list[k] = list[n];
|
||||
list[n] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static T GetRandom<T>(this IEnumerable<T> source, Func<T, bool> predicate, Rand.RandSync randSync = Rand.RandSync.Unsynced)
|
||||
public static T GetRandom<T>(this IReadOnlyList<T> source, Func<T, bool> predicate, Rand.RandSync randSync)
|
||||
{
|
||||
if (predicate == null) { return GetRandom(source, randSync); }
|
||||
return source.Where(predicate).GetRandom(randSync);
|
||||
return source.Where(predicate).ToArray().GetRandom(randSync);
|
||||
}
|
||||
|
||||
public static T GetRandom<T>(this IEnumerable<T> source, Rand.RandSync randSync = Rand.RandSync.Unsynced)
|
||||
/// <summary>
|
||||
/// Gets a random element of a list using one of the synced random number generators.
|
||||
/// It's recommended that you guarantee a deterministic order of the elements of the
|
||||
/// input list via sorting.
|
||||
/// </summary>
|
||||
/// <param name="source">List to pick a random element from</param>
|
||||
/// <param name="randSync">Which RNG to use</param>
|
||||
/// <returns>A random item from the list. Return value should match between clients and
|
||||
/// the server, if applicable.</returns>
|
||||
public static T GetRandom<T>(this IReadOnlyList<T> source, Rand.RandSync randSync)
|
||||
{
|
||||
if (source is IList<T> list)
|
||||
int count = source.Count;
|
||||
return count == 0 ? default : source[Rand.Range(0, count, randSync)];
|
||||
}
|
||||
|
||||
public static T GetRandom<T>(this IReadOnlyList<T> source, Random random)
|
||||
{
|
||||
int count = source.Count;
|
||||
return count == 0 ? default : source[random.Next(0, count)];
|
||||
}
|
||||
|
||||
// The reason these "GetRandomUnsynced" methods exist is because
|
||||
// they can be used on all enumerables; GetRandom can only be used
|
||||
// on lists as they can be sorted to guarantee a certain order.
|
||||
public static T GetRandomUnsynced<T>(this IEnumerable<T> source, Func<T, bool> predicate)
|
||||
{
|
||||
if (predicate == null) { return GetRandomUnsynced(source); }
|
||||
return source.Where(predicate).GetRandomUnsynced();
|
||||
}
|
||||
|
||||
public static T GetRandomUnsynced<T>(this IEnumerable<T> source)
|
||||
{
|
||||
if (source is IReadOnlyList<T> list)
|
||||
{
|
||||
int count = list.Count;
|
||||
return count == 0 ? default : list[Rand.Range(0, count, randSync)];
|
||||
return list.GetRandom(Rand.RandSync.Unsynced);
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = source.Count();
|
||||
return count == 0 ? default : source.ElementAt(Rand.Range(0, count, randSync));
|
||||
return count == 0 ? default : source.ElementAt(Rand.Range(0, count, Rand.RandSync.Unsynced));
|
||||
}
|
||||
}
|
||||
public static T GetRandom<T>(this IEnumerable<T> source, Random random)
|
||||
|
||||
public static T GetRandom<T>(this IEnumerable<T> source, Rand.RandSync randSync)
|
||||
where T : PrefabWithUintIdentifier
|
||||
{
|
||||
if (source is IList<T> list)
|
||||
{
|
||||
int count = list.Count;
|
||||
return count == 0 ? default : list[random.Next(0, count)];
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = source.Count();
|
||||
return count == 0 ? default : source.ElementAt(random.Next(0, count));
|
||||
}
|
||||
return source.OrderBy(p => p.UintIdentifier).ToArray().GetRandom(randSync);
|
||||
}
|
||||
|
||||
public static T RandomElementByWeight<T>(this IEnumerable<T> source, Func<T, float> weightSelector, Rand.RandSync randSync = Rand.RandSync.Unsynced)
|
||||
public static T GetRandom<T>(this IEnumerable<T> source, Func<T, bool> predicate, Rand.RandSync randSync)
|
||||
where T : PrefabWithUintIdentifier
|
||||
{
|
||||
return source.Where(predicate).OrderBy(p => p.UintIdentifier).ToArray().GetRandom(randSync);
|
||||
}
|
||||
|
||||
|
||||
public static T RandomElementByWeight<T>(this IList<T> source, Func<T, float> weightSelector, Rand.RandSync randSync = Rand.RandSync.Unsynced)
|
||||
{
|
||||
float totalWeight = source.Sum(weightSelector);
|
||||
|
||||
float itemWeightIndex = Rand.Range(0f, 1f, randSync) * totalWeight;
|
||||
float currentWeightIndex = 0;
|
||||
|
||||
foreach (T weightedItem in source)
|
||||
for (int i = 0; i < source.Count; i++)
|
||||
{
|
||||
T weightedItem = source[i];
|
||||
float weight = weightSelector(weightedItem);
|
||||
currentWeightIndex += weight;
|
||||
|
||||
@@ -107,6 +141,14 @@ namespace Barotrauma.Extensions
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Iterates over all elements in a given enumerable and discards the result.
|
||||
/// </summary>
|
||||
public static void Consume<T>(this IEnumerable<T> enumerable)
|
||||
{
|
||||
foreach (var _ in enumerable) { /* do nothing */ }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shorthand for !source.Any(predicate) -> i.e. not any.
|
||||
/// </summary>
|
||||
@@ -155,6 +197,27 @@ namespace Barotrauma.Extensions
|
||||
if (value != null) { source.Add(value); }
|
||||
}
|
||||
|
||||
public static ImmutableDictionary<TKey, TValue> ToImmutableDictionary<TKey, TValue>(this IEnumerable<(TKey, TValue)> enumerable)
|
||||
{
|
||||
return enumerable.ToDictionary().ToImmutableDictionary();
|
||||
}
|
||||
|
||||
public static Dictionary<TKey, TValue> ToDictionary<TKey, TValue>(this IEnumerable<(TKey, TValue)> enumerable)
|
||||
{
|
||||
var dictionary = new Dictionary<TKey, TValue>();
|
||||
foreach (var (k,v) in enumerable)
|
||||
{
|
||||
dictionary.Add(k, v);
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
public static Dictionary<TKey, TValue> ToMutable<TKey, TValue>(this ImmutableDictionary<TKey, TValue> immutableDictionary)
|
||||
{
|
||||
if (immutableDictionary == null) { return null; }
|
||||
return new Dictionary<TKey, TValue>(immutableDictionary);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether a given collection has at least a certain amount
|
||||
/// of elements for which the predicate returns true.
|
||||
@@ -172,6 +235,18 @@ namespace Barotrauma.Extensions
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Equivalent to LINQ's Enumerable.Concat. The main difference is that this
|
||||
/// takes advantage of ICollection<T> optimizations for Enumerable.Contains
|
||||
/// and Enumerable.Count.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static ICollection<T> CollectionConcat<T>(this IEnumerable<T> self, IEnumerable<T> other)
|
||||
=> new CollectionConcat<T>(self, other);
|
||||
|
||||
public static IReadOnlyList<T> ListConcat<T>(this IEnumerable<T> self, IEnumerable<T> other)
|
||||
=> new ListConcat<T>(self, other);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum element in a given enumerable, or null if there
|
||||
/// aren't any elements in the input.
|
||||
@@ -188,6 +263,10 @@ namespace Barotrauma.Extensions
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static TOut? MaxOrNull<TIn, TOut>(this IEnumerable<TIn> enumerable, Func<TIn, TOut> conversion)
|
||||
where TOut : struct, IComparable<TOut>
|
||||
=> enumerable.Select(conversion).MaxOrNull();
|
||||
|
||||
public static int FindIndex<T>(this IReadOnlyList<T> list, Predicate<T> predicate)
|
||||
{
|
||||
for (int i=0; i<list.Count; i++)
|
||||
|
||||
Reference in New Issue
Block a user