Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Two functions below: one returns T[] and one returns IEnumerable<T> using yield.
- // Has been tested for uniform distribution and has excellent performance.
- // Should NOT be used as a shuffling algorithm by requesting all items to be picked, as this will return the set of values unchanged.
- // Requires System.Random object:
- // private static readonly Random Random = new Random();
- /// <summary>
- /// Randomly picks '<paramref name="count"/>' number of elements from the set of <paramref name="values"/>.
- /// </summary>
- /// <typeparam name="T">The type of values.</typeparam>
- /// <param name="values">The values to pick from.</param>
- /// <param name="count">The number of values to pick.</param>
- /// <exception cref="ArgumentNullException">Thrown if <paramref name="values"/> is null.</exception>
- /// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="count"/> is negative.</exception>
- /// <exception cref="ArgumentException">Throw if <paramref name="count"/> is greater than the number of values.</exception>
- public static T[] RandomlyPick<T>(this IEnumerable<T> values, int count)
- {
- if (values == null) { throw new ArgumentNullException(nameof(values)); }
- if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count), "Count cannot be negative."); }
- T[] allValues = values as T[] ?? values.ToArray();
- if (count == allValues.Length) { return allValues; }
- if (count > allValues.Length) { throw new ArgumentException("Count is greater than number of values.", nameof(count)); }
- T[] returnValues = new T[count];
- for (int i = 0; i < count; i++)
- {
- int index = Random.Next(i, allValues.Length);
- T temp = allValues[i];
- returnValues[i] = allValues[i] = allValues[index];
- allValues[index] = temp;
- }
- return returnValues;
- }
- /// <summary>
- /// Randomly picks '<paramref name="count"/>' number of elements from the set of <paramref name="values"/>.
- /// </summary>
- /// <typeparam name="T">The type of values.</typeparam>
- /// <param name="values">The values to pick from.</param>
- /// <param name="count">The number of values to pick.</param>
- /// <exception cref="ArgumentNullException">Thrown if <paramref name="values"/> is null.</exception>
- /// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="count"/> is negative.</exception>
- /// <exception cref="ArgumentException">Throw if <paramref name="count"/> is greater than the number of values.</exception>
- public static IEnumerable<T> RandomlyPick<T>(this IEnumerable<T> values, int count)
- {
- if (values == null) { throw new ArgumentNullException(nameof(values)); }
- if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count), "Count cannot be negative."); }
- T[] allValues = values as T[] ?? values.ToArray();
- if (count == allValues.Length)
- {
- foreach (T value in allValues) { yield return value; }
- yield break;
- }
- if (count > allValues.Length) { throw new ArgumentException("Count is greater than number of values.", nameof(count)); }
- for (int i = 0; i < count; i++)
- {
- int index = Random.Next(i, allValues.Length);
- T temp = allValues[i];
- yield return allValues[i] = allValues[index];
- allValues[index] = temp;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement