I have got an IEnumerable collection as follows
var result1 = GetResult1() // Returns 2,4,5,6
I have to juggle the elements and create another collection in a random way which should result as follows:
var result2 = GetResult2(result1) // Returns 2,4,5,6 in a random order.
// An example output would be 4,6,2,5 in the resultant collection.
I have done this by the following means:
var result1 = GetResult1();
var random = new Random();
var result2 = result1.OrderBy(order=>random.Next());
However the issue with this is that if I access result2 the elements in result2 gets shuffled again, i.e if I output the results of result2 to a console twice, the elements are juggled again.
Can you please advice how to keep this uniform. i.e once I juggle the collection, it should remain the same way thereafter. I have to use lazy evaluation though, since the results are very huge in size.
You are looking for a shuffle algorithm.
See following SO threads to provide nice extensions method to do the job:
Is using Random and OrderBy a good shuffle algorithm?
An extension method on IEnumerable needed for shuffling
To answer your question "why is that shuffled again?", it's because of how OrderBy
works (lazy execution). You could try:
var result2 = result1.OrderBy(order=>random.Next()).ToList();
I see you require lazy evaluation for the results, if that is the case, what you can do is this:
var randomNumbers = result1.Select(r => random.Next()).ToArray();
var orderedResult = result1.Zip(randomNumbers, (r, o) => new { Result = r, Order = o })
.OrderBy(o => o.Order)
.Select(o => o.Result);
By calling ToArray()
on the random numbers, these will not change. When you finally desire the items in result1
, you can zip the items with the random numbers, OrderBy
the random number and Select
the result.
As long as the items in result1
come in the same order, the result in orderedResult
should be the same each time.
You can use ToList()
like this:
var result2 = result1.OrderBy(order=>random.Next()).ToList();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With