1

I have to make a list containing objects. And the objects need to be in random order. Here I give them random numbers:

Random tal = new Random();
list1[i].nummer = tal.Next(list1.Count);
listGold.Add(list1[i]);

And now i just need to order them by number. Which I thought linq could do for me. But it can't :S

I am trying this:

RepeaterSponsorGold.DataSource = listGold.OrderBy(n => n.nummer);
RepeaterSponsorGold.DataBind();

to order my list by nummer and to put the list into my repater. But the lsit doesn't seem to be sorted... or doesn't seem to get random numbers. i don't know which. Can anybody see what i am doing wrong??

RePierre
  • 9,358
  • 2
  • 20
  • 37
Oedum
  • 796
  • 2
  • 9
  • 28
  • 2
    Ordering by random can have a weird distribution. You should use http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle – Dave Bish May 21 '12 at 13:34
  • 3
    Is the `new Random()` being created inside the loop that you are using to set the random number? You should onyl create a new Random() once and then use that instance from then on, otherwise you will likely be getting the same random number out repeatedly. – Chris May 21 '12 at 13:34
  • Step through your code and make sure that your random numbers are set correctly. – jrummell May 21 '12 at 13:35
  • What is the value of list1.Count? What does your list contain in the `nummer` field? – Robaticus May 21 '12 at 13:35

5 Answers5

3

Try

RepeaterSponsorGold.DataSource = listGold.OrderBy(n => n.nummer).ToList();
Marko Juvančič
  • 5,792
  • 1
  • 25
  • 41
2

If you need to sort in random order you could try:

var listGold = list1.OrderBy(n => Guid.NewGuid());

without the need to use Random.

Marco
  • 56,740
  • 14
  • 129
  • 152
  • 2
    This is not a great solution if performance is a concern. Sorting is an O(n*log(n)) operation. Shuffling only needs to be O(n). The 'shuffling algorithm' link shows a better way. – Dave Bish May 21 '12 at 13:41
  • It's also not a great solution if randomness is a concern! Guids are designed to be unique, they're not necessarily random. – LukeH May 21 '12 at 13:57
2

You should't use Random() to shuffle a list, as it can produce determanistic distributions.

Instead, use a suffle:

Randomize a List<T>

public static void Shuffle<T>(this IList<T> list)  
{  
    Random rng = new Random();  
    int n = list.Count;  
    while (n > 1) {  
        n--;  
        int k = rng.Next(n + 1);  
        T value = list[k];  
        list[k] = list[n];  
        list[n] = value;  
    }  
}

....

listGold.Shuffle();
Community
  • 1
  • 1
Dave Bish
  • 19,263
  • 7
  • 46
  • 63
0

How about this:

List<string> list = new List<string>()
                        {
                            "Blue",
                            "Brown",
                            "Beige",
                            "Red",
                            "Black"
                        };
Random random = new Random();
var orderedList = list.Select(c => new {Item = c, Order = random.Next()})
    .OrderBy(i=>i.Item)
    .Select(x=>x.Item).ToList();

orderedList.ForEach(x=>Console.WriteLine(x));
Aliostad
  • 80,612
  • 21
  • 160
  • 208
0

You have a couple of issues.

The most important is that you should only ever have a single instance of Random, and use it repeatedly, rather than invoking a new one every time.

Second, by using the list count as your seed, you'll get a roughly sequential list.

list1[i].nummer = tal.Next(list1.Count);

Because you're using your list.Count as your seed you'll get a list that is roughly in the order they were added.

Instead try:

Enumerable.Range(0,100)
    .ToDictionary(k=> Guid.NewGuid())
    .OrderBy(o => o.Key).Select(s => s.Value).ToList()

Using the Guids will give you a more natural randomization than Random.

Thinking Sites
  • 3,494
  • 17
  • 30