Client LuaCsForBarotrauma
IEnumerableExtensions.cs
1 using System.Collections.Generic;
2 using System;
3 using System.Linq;
4 using System.Collections.Immutable;
5 
7 {
8  public static class IEnumerableExtensions
9  {
13  public static T[] Randomize<T>(this IList<T> source, Rand.RandSync randSync = Rand.RandSync.Unsynced)
14  {
15  return source.OrderBy(i => Rand.Value(randSync)).ToArray();
16  }
17 
21  public static void Shuffle<T>(this IList<T> list, Rand.RandSync randSync = Rand.RandSync.Unsynced)
22  => list.Shuffle(Rand.GetRNG(randSync));
23 
24  public static void Shuffle<T>(this IList<T> list, Random rng)
25  {
26  int n = list.Count;
27  while (n > 1)
28  {
29  n--;
30  int k = rng.Next(n + 1);
31  T value = list[k];
32  list[k] = list[n];
33  list[n] = value;
34  }
35  }
36 
37  public static T GetRandom<T>(this IReadOnlyList<T> source, Func<T, bool> predicate, Rand.RandSync randSync)
38  {
39  if (predicate == null) { return GetRandom(source, randSync); }
40  return source.Where(predicate).ToArray().GetRandom(randSync);
41  }
42 
52  public static T GetRandom<T>(this IReadOnlyList<T> source, Rand.RandSync randSync)
53  {
54  int count = source.Count;
55  return count == 0 ? default : source[Rand.Range(0, count, randSync)];
56  }
57 
58  public static T GetRandom<T>(this IReadOnlyList<T> source, Random random)
59  {
60  int count = source.Count;
61  return count == 0 ? default : source[random.Next(0, count)];
62  }
63 
64  // The reason these "GetRandomUnsynced" methods exist is because
65  // they can be used on all enumerables; GetRandom can only be used
66  // on lists as they can be sorted to guarantee a certain order.
67  public static T GetRandomUnsynced<T>(this IEnumerable<T> source, Func<T, bool> predicate)
68  {
69  if (predicate == null) { return GetRandomUnsynced(source); }
70  return source.Where(predicate).GetRandomUnsynced();
71  }
72 
73  public static T GetRandomUnsynced<T>(this IEnumerable<T> source)
74  {
75  if (source is IReadOnlyList<T> list)
76  {
77  return list.GetRandom(Rand.RandSync.Unsynced);
78  }
79  else
80  {
81  int count = source.Count();
82  return count == 0 ? default : source.ElementAt(Rand.Range(0, count, Rand.RandSync.Unsynced));
83  }
84  }
85 
86  public static T GetRandom<T>(this IEnumerable<T> source, Random rand)
87  where T : PrefabWithUintIdentifier
88  {
89  return source.OrderBy(p => p.UintIdentifier).ToArray().GetRandom(rand);
90  }
91 
92  public static T GetRandom<T>(this IEnumerable<T> source, Rand.RandSync randSync)
93  where T : PrefabWithUintIdentifier
94  {
95  return source.OrderBy(p => p.UintIdentifier).ToArray().GetRandom(randSync);
96  }
97 
98  public static T GetRandom<T>(this IEnumerable<T> source, Func<T, bool> predicate, Rand.RandSync randSync)
99  where T : PrefabWithUintIdentifier
100  {
101  return source.Where(predicate).OrderBy(p => p.UintIdentifier).ToArray().GetRandom(randSync);
102  }
103 
104  public static T GetRandomByWeight<T>(this IEnumerable<T> source, Func<T, float> weightSelector, Rand.RandSync randSync)
105  {
106  return ToolBox.SelectWeightedRandom(source, weightSelector, randSync);
107  }
108 
113  public static void ForEachMod<T>(this IEnumerable<T> source, Action<T> action)
114  {
115  if (source.None()) { return; }
116  var temp = new List<T>(source);
117  temp.ForEach(action);
118  }
119 
124  public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
125  {
126  foreach (var item in source)
127  {
128  action(item);
129  }
130  }
131 
135  public static void Consume<T>(this IEnumerable<T> enumerable)
136  {
137  foreach (var _ in enumerable) { /* do nothing */ }
138  }
139 
143  public static bool None<T>(this IEnumerable<T> source, Func<T, bool> predicate = null)
144  {
145  if (predicate == null)
146  {
147  return !source.Any();
148  }
149  else
150  {
151  return !source.Any(predicate);
152  }
153  }
154 
155  public static bool Multiple<T>(this IEnumerable<T> source, Func<T, bool> predicate = null)
156  {
157  if (predicate == null)
158  {
159  return source.Count() > 1;
160  }
161  else
162  {
163  return source.Count(predicate) > 1;
164  }
165  }
166 
167  public static IEnumerable<T> ToEnumerable<T>(this T item)
168  {
169  yield return item;
170  }
171 
172  // source: https://stackoverflow.com/questions/19237868/get-all-children-to-one-list-recursive-c-sharp
173  public static IEnumerable<T> SelectManyRecursive<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> selector)
174  {
175  var result = source.SelectMany(selector);
176  if (!result.Any())
177  {
178  return result;
179  }
180  return result.Concat(result.SelectManyRecursive(selector));
181  }
182 
183  public static void AddIfNotNull<T>(this IList<T> source, T value)
184  {
185  if (value != null) { source.Add(value); }
186  }
187 
188  public static NetCollection<T> ToNetCollection<T>(this IEnumerable<T> enumerable) => new NetCollection<T>(enumerable.ToImmutableArray());
189 
197  public static bool AtLeast<T>(this IEnumerable<T> source, int amount, Predicate<T> predicate)
198  {
199  foreach (T elem in source)
200  {
201  if (predicate(elem)) { amount--; }
202  if (amount <= 0) { return true; }
203  }
204  return false;
205  }
206 
213  public static ICollection<T> CollectionConcat<T>(this IEnumerable<T> self, IEnumerable<T> other)
214  => new CollectionConcat<T>(self, other);
215 
216  public static IReadOnlyList<T> ListConcat<T>(this IEnumerable<T> self, IEnumerable<T> other)
217  => new ListConcat<T>(self, other);
218  }
219 }
Prefab that has a property serves as a deterministic hash of a prefab's identifier....