Randomizing Elements in a List (C#)

July 12th, 2007     |     View Comments

For a project I am currently working on, I needed the ability to randomly sort a list of strings. Before I describe this further, the following is the C# code I used:

private Random ranNum;
 
private List<string> GetRandomStringList(List<string> inputList)
{
ranNum = new Random();
int randomNumber;
 
for (int i = 0; i < inputList.Count; i++)
{
randomNumber = ranNum.Next(inputList.Count);
 
string currentString = inputList[i];
string randomString = inputList[randomNumber];
 
inputList[i] = randomString;
inputList[randomNumber] = currentString;
 
}
return inputList;
}

The approach I use in the above code is fairly simple. I iterate through the list, and at each list item, I store two pieces of information – the current list item designated by the i index (currentString) and a random list item (randomString) picked randomly through randomNumber:

arrayList

With the two pieces of information, I simply swap their locations in the list. I set the value at position i to that of randomString, and I set the value at position randomNumber to be currentString:

swapped_arrayList

Now, the values in our list are out of order, and since we had no control over where randomNumber was going to be, you can say that the list is randomly out of order. This store and swap operation continues until our index value i has reached the last element of the list. Since no operations are duplicated beyond the length of our list, this operation runs in linear time.

EDIT: Be sure to read OJ’s comments to this post where he outlines ways in improving the code.

Cheers!
Kirupa :)

View Comments to “Randomizing Elements in a List (C#)”

  1. OJ Says:

    Hi Kirupa,

    I just have a few points from a development perspective:

    The ‘ranNum’ variable should be local to the GetRandomStringList(), since that’s where you’re constructing it anyway. Either that or construct the ‘ranNum’ variable in the object’s constructor rather than recreate it each time the function is called.

    Let’s assume I used your current code in the following manner:
    List x = SomeBigLongListOfStuff();
    List y = GetRandomStringList( x );
    List z = GetRandomStringList( x );
    I’d expect x, y and z to all be different – but they’re all exactly the same! They reference the same list, and hence have the same content.

    The function name GetRandomStringList() doesn’t imply that the list you pass in (‘inputList’) is going to be modified, and hence is a bit misleading. IMHO, I think you should either change the function signature to ‘private void RandomiseStringList( List list )’ which implies that ‘list’ will be modified, or you should create a whole new list inside your GetRandomStringList() function and leave the input parameter alone. This improves readability of your code, and makes this much more intuitive.

    Creating the ‘currentString’ variable isn’t necessary. You could do the exact same thing without adding another variable to your code:
    for( int i = 0; i

    Cheers :)
    OJ

  2. OJ Says:

    PS. Any chance you could modify my comment so that the code appears… please? :)

  3. kirupa Says:

    Good points OJ, and I definitely agree with you about how my current version doesn’t help inform the developer whether the input will get mutated or not. Do you know of a good book/resource for learning proper coding styles and techniques?

    What is the full code you want me to post? I am guessing it is:

    for (int i = 0; i < inputList.Count; i++)
    {
       randomNumber = ranNum.Next(inputList.Count);

       string randomString = inputList[randomNumber];
     
       inputList[i] = randomString;
       inputList[randomNumber] = inputList[i];
    }  

    If it isn’t, you can e-mail it to me at kirupa.at.kirupa.com, and I’ll add it up :)

    Cheers!
    Kirupa

  4. OJ Says:

    Hi Kirupa,

    Yup, that was it :) Thanks very much. The first example had a few references to “List”, which should have been “List<string>”, but other than that it’s all good.

    As far as books go, I think that any prospective coder will get a great deal out of reading Steve Mcconnell’s Code Complete 2. I’ve read this one a few times, and I get something new out of it teach time! (That makes me sound like I don’t pay attention when I’m reading ;) ). Anyway, I think you’ll enjoy it, there’s some fantastic stuff in there.

    Cheers mate
    OJ

  5. OJ Says:

    Thanks for the plug mate! I’m in the process of writing up a blog post that was inspired by our discussion.

    Cheers ;)
    OJ

  6. Avoid Writing Unintuitive Code at OJ’s rants Says:

    [...] This blog post was inspired by a brief chat I had recently with Kirupa of kirupa.com. I subscribe to his blog’s RSS feed as he comes out with some really good stuff. His recent post which showed a way of shuffling a List of strings (using C#) inspired a bit of thought on the topic of code readability, how and when it’s learned (if at all) and why there is so little of it around. [...]

  7. Gav Says:

    Hi,

    Unless i’m mistaken OJ’s code doesn’t actually work.

    Shouldn’t the two assignments to inputList be the other way round? Otherwise you move the random string to position i and then put the random string back where it started?

    E.g.

    inputList[0] = “String1″
    inputList[1] = “String2″

    i=0, randomNumber=1
    randomString = inputList[1] = “String2″
    inputList[0] = randomString = “String2″
    inputList[randomNumber] = inputList[0] = “String2″

    inputList[0] = “String2″
    inputList[1] = “String2″

  8. kirupa Says:

    Gav – you are right. I didn’t test OJ’s code, but it looks like swapping them like you mention works correctly:

    inputList[randomNumber] = inputList[i];
    inputList[i] = randomString;

    Cheers!
    Kirupa :)

  9. kirupaBlog - If it isn’t broken, take it apart and fix it! » Blog Archive » Interesting Links #3: Write Better Code, AK-47, Webcams… Says:

    [...] Writing Intuitive CodeA nice article extending the comments made in my Randomizing Elements in a List post on how code readability and maintainability can be improved.  [...]

  10. Avoid Writing Unintuitive Code | OJ's rants Says:

    [...] I subscribe to his blog’s RSS feed as he comes out with some really good stuff. His recent post which showed a way of shuffling a List of strings (using C#) inspired a bit of thought on the topic [...]

  11. linkwheel Says:

    Fantastic put up! This might assist linkwheel a number of folks discover out about this matter. Do you need to incorporate video clips together with these? It may undoubtedly linkwheel assist out. Your purpose linkwheel was spot on and owing to you; I most likely will not have to explain linkwheel everything to my pals. I can simply direct them here. Anyway, in my language, there will not be a lot good linkwheel supply like this.

  12. rss feed Says:

    Have you ever thought about including rss feed a bit bit more than just your ideas? I mean, what rss feed you say is vital and everything. But its got no punch rss feed, no pop! Possibly for those who added a pic or two, a video? You possibly can have such a extra highly rss feed effective blog if you happen to let individuals SEE what youre talking rss feed about instead of simply studying it. Anyway, in my language, there aren’t a lot rss feed good source like this.

  13. Mallory Toelle Says:

    In hunting wisdom, the post was as good as, “Make no small plans for they have no power to stir the soul.”

Leave a Reply

blog comments powered by Disqus