1

I have some code to randomize an extracted list of results but I'd prefer to not include the random variable as part of the extracted result, any ideas? Here's my code:

var rnd = new Random();

var numList = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var extracted = (from n1 in numList
                 from n2 in numList
                 from n3 in numList
                 from n4 in numList
                     where n1 + n2 + n3 + n4 > 20
                 select new { n1, n2, n3, n4, Rnd = rnd.NextDouble() })
                 .OrderBy(z => z.Rnd).ToList();
user247702
  • 23,641
  • 15
  • 110
  • 157
chillydk147
  • 385
  • 1
  • 10
  • Really what you should do is use an [actual shuffling algorithm](http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle) instead of sorting on a random value, which is both less efficient and more error prone. – Servy May 28 '14 at 19:16
  • The Random class works fine for what I'm doing, thanks anyway for the suggestion. – chillydk147 May 28 '14 at 19:20
  • I'm not suggesting that you not use the `Random` class. I'm suggesting that you use it in a way that actually produces a well defined shuffle, because your current option does not reliably produce uniformly shuffled data. – Servy May 28 '14 at 19:21

1 Answers1

2

If you need to randomize output, just order by random values, without including them in selected data:

var rnd = new Random();
var numList = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

var extracted =  from n1 in numList
                 from n2 in numList
                 from n3 in numList
                 from n4 in numList
                 where n1 + n2 + n3 + n4 > 20
                 orderby rnd.NextDouble()
                 select new { n1, n2, n3, n4 }; // you can use ToList() 
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
  • 1
    Thanks, looks so obvious now that I see it, feel silly now asking the question. – chillydk147 May 28 '14 at 19:17
  • @user3165925 btw you can use `rnd.Next()` - it will give you random values, just as `NextDouble()` but without converting integer to double – Sergey Berezovskiy May 28 '14 at 19:18
  • @SergeyBerezovskiy Although it has a dramatically higher probability of resulting in collisions, further increasing the bias introduced by the fact that sorting on a random number is not in fact shuffling data. – Servy May 28 '14 at 19:22
  • @Servy this is a simplest approach, which should be used if performance is not an issue, and you don't need perfect randomization. Implementation time - 5 seconds, very easy to understand – Sergey Berezovskiy May 28 '14 at 19:26
  • 1
    It seems fine for me to use normal random class, here's an output of calling the same function 7 times – chillydk147 May 28 '14 at 19:27
  • 86, 32, 64, 83, 99, 33, 72, 62, 67, = 598 77, 36, 84, 69, 67, 85, 49, 90, 44, = 601 97, 37, 95, 37, 71, 61, 66, 93, 41, = 598 67, 67, 79, 33, 87, 68, 132, 29, 35, = 597 122, 45, 31, 67, 31, 87, 81, 54, 80, = 598 124, 28, 46, 132, 68, 39, 27, 67, 67, = 598 39, 95, 95, 39, 44, 83, 74, 44, 88, = 601 65, 68, 83, 70, 31, 81, 70, 64, 67, = 599 – chillydk147 May 28 '14 at 19:28
  • @SergeyBerezovskiy As opposed to spending 10 seconds copying a *real* shuffling algorithm into your code, having reliable, efficient, effective, readable, and maintainable shuffling. Added cost, 5 seconds. – Servy May 28 '14 at 19:28
  • @chillydk147 The question is not whether or not you use the `Random` class (unless you're in a context in which you really do need cryptographic strength randomness) but *how* you use it. – Servy May 28 '14 at 19:29
  • @SergeyBerezovskiy I'm not even saying it's the primary reason. It's simply a nice added benefit to get a fairly dramatic efficiency boost while also fixing all of the other important issues such as what probably *is* the most important issue, removing a bias in the shuffling algorithm. – Servy May 28 '14 at 19:30
  • @Servy Are there any examples of this "Fisher–Yates shuffle" packaged within a C# Method which I can quickly add to my program? – chillydk147 May 28 '14 at 19:31
  • @chillydk147 Yes, there are. A simple Google (or SO) search can help you find one in seconds. – Servy May 28 '14 at 19:32
  • @chillydk147 here is sample http://stackoverflow.com/questions/1287567/is-using-random-and-orderby-a-good-shuffle-algorithm?lq=1 – Sergey Berezovskiy May 28 '14 at 19:37