Advertisement
Guest User

Untitled

a guest
Jul 21st, 2017
53
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.12 KB | None | 0 0
  1. // Two functions below: one returns T[] and one returns IEnumerable<T> using yield.
  2.  
  3. // Has been tested for uniform distribution and has excellent performance.
  4. // Should NOT be used as a shuffling algorithm by requesting all items to be picked, as this will return the set of values unchanged.
  5.  
  6. // Requires System.Random object:
  7. // private static readonly Random Random = new Random();
  8.  
  9. /// <summary>
  10. /// Randomly picks '<paramref name="count"/>' number of elements from the set of <paramref name="values"/>.
  11. /// </summary>
  12. /// <typeparam name="T">The type of values.</typeparam>
  13. /// <param name="values">The values to pick from.</param>
  14. /// <param name="count">The number of values to pick.</param>
  15. /// <exception cref="ArgumentNullException">Thrown if <paramref name="values"/> is null.</exception>
  16. /// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="count"/> is negative.</exception>
  17. /// <exception cref="ArgumentException">Throw if <paramref name="count"/> is greater than the number of values.</exception>
  18. public static T[] RandomlyPick<T>(this IEnumerable<T> values, int count)
  19. {
  20. if (values == null) { throw new ArgumentNullException(nameof(values)); }
  21. if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count), "Count cannot be negative."); }
  22.  
  23. T[] allValues = values as T[] ?? values.ToArray();
  24. if (count == allValues.Length) { return allValues; }
  25. if (count > allValues.Length) { throw new ArgumentException("Count is greater than number of values.", nameof(count)); }
  26.  
  27. T[] returnValues = new T[count];
  28.  
  29. for (int i = 0; i < count; i++)
  30. {
  31. int index = Random.Next(i, allValues.Length);
  32. T temp = allValues[i];
  33. returnValues[i] = allValues[i] = allValues[index];
  34. allValues[index] = temp;
  35. }
  36.  
  37. return returnValues;
  38. }
  39.  
  40. /// <summary>
  41. /// Randomly picks '<paramref name="count"/>' number of elements from the set of <paramref name="values"/>.
  42. /// </summary>
  43. /// <typeparam name="T">The type of values.</typeparam>
  44. /// <param name="values">The values to pick from.</param>
  45. /// <param name="count">The number of values to pick.</param>
  46. /// <exception cref="ArgumentNullException">Thrown if <paramref name="values"/> is null.</exception>
  47. /// <exception cref="ArgumentOutOfRangeException">Thrown if <paramref name="count"/> is negative.</exception>
  48. /// <exception cref="ArgumentException">Throw if <paramref name="count"/> is greater than the number of values.</exception>
  49. public static IEnumerable<T> RandomlyPick<T>(this IEnumerable<T> values, int count)
  50. {
  51. if (values == null) { throw new ArgumentNullException(nameof(values)); }
  52. if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count), "Count cannot be negative."); }
  53.  
  54. T[] allValues = values as T[] ?? values.ToArray();
  55. if (count == allValues.Length)
  56. {
  57. foreach (T value in allValues) { yield return value; }
  58. yield break;
  59. }
  60. if (count > allValues.Length) { throw new ArgumentException("Count is greater than number of values.", nameof(count)); }
  61.  
  62. for (int i = 0; i < count; i++)
  63. {
  64. int index = Random.Next(i, allValues.Length);
  65. T temp = allValues[i];
  66. yield return allValues[i] = allValues[index];
  67. allValues[index] = temp;
  68. }
  69. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement