BLOG.CSHARPHELPER.COM: Pick N random items from an array of M items in C#
Pick N random items from an array of M items in C#
Picking one random item from an array is easy. Just use a Random object as demonstrated by the example Select a random object from an array (or other collection) in C#.
You can extend this idea a bit but there are problems. For example, if you pick a second item randomly, what happens if you pick the same item again? The easiest solution would be to use the following item but that would increase the odds of picking the following item (from 1 in N to 2 in N). And what if the item you picked twice is the last item so there is no following item? Things get even messier if you need to pick more items.
A better strategy is to ignore any duplicate picks and continue picking random items until you pick a new one. That works but can slow you down, particularly if you need to pick a large percentage of the total number of items (for example, pick 90 out of 100).
This example uses an even better strategy, shown in the following code. PickItems is a static method in the Randomizer class so it's easy to use from any application. It uses a generic type parameter so it can pick items randomly from an array of any type of item.
// Pick num_picks items randomly. public static T[] PickItems(T[] items, int num_picks) { // Make a copy of the items so we // don't mess up the original array. T[] items_copy = (T[])items.Clone();
// Pick the items. Random rand = new Random(); for (int i = 0; i < num_picks; i++) { // Pick an item between position i // and the end of the array. int j = rand.Next(i, items.Length);
// Swap this item to position i. T temp = items_copy[i]; items_copy[i] = items_copy[j]; items_copy[j] = temp; }
// Make and return the result array. T[] result = new T[num_picks]; Array.Copy(items_copy, result, num_picks); return result; }
The code first makes a copy of the array so it doesn't mess up the original. If you don't care about the order if items in the original array, you can skip this step and save some time.
Next the code makes a Random object and then enters a loop to generate the random picks in positions 0 through num_picks - 1. For the i-th pick, the code randomly selects an item between position i and the end of the array. It then swaps that item into position i and continues.
After it has randomly picked num_picks items, the code copies those items into a result array and returns it.
Note that this technique is similar to the one used by the example Randomize the items in an array in C# but it stops when it has randomized enough items.
Comments