C# Shuffle Array

You want to shuffle an array, randomly reordering all elements, with results that are mathematically correct. Some solutions exist but do not give random results always. Here we look at a simple way to shuffle an array, using the C# programming language.

There are many ways to reorder array elements randomly.        
... This article shows how you can use KeyValuePair.           
... This method is as accurate as your random number generator.

Shuffling array

First, here we see an approach to shuffling a string[] array that is not the classic, optimized Fisher-Yates shuffle. However, this approach is mathematically random and will not cause strange biases in your code. This is true because it performs all the operations together, rather than one at a time.

~~~ Class that implements array shuffling (C#) ~~~

using System;
using System.Collections.Generic;
using System.Linq;

/// <summary>
/// Slow but reliable method for randomizing string array
/// </summary>
static class RandomStringArrayTool
{
    /// <summary>
    /// Stores the current random number
    /// </summary>
    static Random _random = new Random();

    /// <summary>
    /// Return randomized version of the string array
    /// </summary>
    public static string[] RandomizeStrings(string[] arr)
    {
        List<KeyValuePair<int, string>> list = new List<KeyValuePair<int, string>>();
        // Add all strings from array
        // Add new random int each time
        foreach (string s in arr)
        {
            list.Add(new KeyValuePair<int, string>(_random.Next(), s));
        }
        // Sort the list by the random number
        var sorted = from item in list
                     orderby item.Key
                     select item;
        // Allocate new string array
        string[] result = new string[arr.Length];
        // Copy values to array
        int index = 0;
        foreach (KeyValuePair<int, string> pair in sorted)
        {
            result[index] = pair.Value;
            index++;
        }
        // Return copied array
        return result;
    }
}

Description. The method here uses the KeyValuePair<T, V> data structure that is included in System.Collections.Generic. It allocates another array containing the string[] elements and pairs them with a random number. Finally, it sorts.

This method is equally random as generating a random set of integers one-by-one. If you only randomize one element at a time, and then randomize the rest separately, you will get biases.

We randomize the entire array all at once, which will result in consistently random results. I decided to use this approach instead of the optimized algorithms because this code wasn't on a hot path in my program.

Random numbers. It stores a Random number generator as a static field, which means you can call the RandomizeStrings method repeatedly and will get good results.

See Random Number Generator.

Using the method

Usually, simpler methods that do not randomize all elements at once will suffice, but for more important applications, you want the very best results. Use this code in your Program.cs file for the demo. This works on a string array.

See String Array.

=== Example code to shuffle array (C#) ===

using System;

class Program
{
    static void Main()
    {
        string[] arr = new string[]
        {
            "cat",
            "animal",
            "abacus",
            "framework"
        };
        string[] shuffle = RandomStringArrayTool.RandomizeStrings(arr);
        foreach (string s in shuffle)
        {
            Console.WriteLine(s);
        }
    }
}

=== Output of the code ===

abacus
animal
framework
cat

Corrections

This article previously showed a naive method that used OrderBy in LINQ, but was not mathematically sound. Dot Net Perls apologizes for any non-optimal results from the previous method. This method is mathematically sound, as noted in the Wikipedia article. [See "Comparison with other shuffling algorithms"] Wikipedia notes that this approach is sometimes faster in high-level languages, but it is very unlikely to be faster in C#.

Visit en.wikipedia.org.

Summary

Here we use a mathematically sound approach for shuffling an array. The problem with this method is that it is not optimally fast, but for my use this wasn't important. If you need performance, use an implementation of Fisher-Yates. We saw an example of using the LINQ query syntax with a List of KeyValuePair structs, proving a convenient way of reordering collections.

See Random Overview.

© 2007-2010 Sam Allen. All rights reserved.

Dot Net Perls  Sam Allen