tags:

views:

62

answers:

4

Hello Stackoverflow.

How do I randomize the order of the files I get out of:

string[] files = Directory.GetFiles("folder");

Thank you! :-)

+4  A: 

One option is to use Random:

Random rng = new Random();

and then:

var randomOrderFiles = files.OrderBy(f => rng.Next());

This isn't the most efficient method as it takes O(nlogn). If this is a problem for you, better algorithms exist.

Kobi
+2  A: 

If you can't use Linq the following method should work:

static Random rand = new Random();
static void Randomize<T>(IList<T> list)
{
    for (int i = list.Count - 1; i > 0; i--)
    {
        int i2 = rand.Next(i + 1);
        if (i2 != i)
        {
            T tmp = list[i2];
            list[i2] = list[i];
            list[i] = tmp;
        }
    }
}
ho1
aka [Fisher–Yates Shuffle](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) - this can be done in-place (as you did), and has complexity of O(n).
Kobi
A: 
Rob
+2  A: 

Create a helper/extension method to shuffle the array returned from GetFiles. The example below performs a Fisher-Yates-Durstenfeld shuffle, which is O(n) and should give unbiased distribution.

string[] randomOrder = Directory.GetFiles("folder").ShuffleInPlace();

// ...

public static class ListExtensions
{
    public static void ShuffleInPlace<T>(this IList<T> source)
    {
        if (source == null)
            throw new ArgumentNullException("source");

        Random rng = new Random();

        for (int n = 0; n < source.Count - 1; n++)
        {
            int k = rng.Next(n, source.Count);

            T temp = source[k];
            source[k] = source[n];
            source[n] = temp;
        }
    }
}

If you prefer to return a new sequence -- à la LINQ -- rather than doing an in-place shuffle of the existing array, then you could create a suitable Shuffle method and use that instead.

LukeH