Reputation: 39364
Using C# 6 I have a list of names alphabetically ordered:
List<String> names = getAlphabeticallyOrderedNames();
I need to shuffle the names but I want to get the same result every time. So I cannot use:
List<String> shuffledNames = names.OrderBy(x => Guid.NewGuid());
I then tried something like:
List<String> shuffledNames = names.OrderBy(x => "d2fda3b5-4089-43f9-ba02-f68d138dee49");
Or
List<String> shuffledNames = names.OrderBy(x => Int32.MaxValue);
But the names are not shuffled ...
How can I solve this?
Upvotes: 2
Views: 2862
Reputation: 39364
An Enumerable extension using Yield and having Seed value as parameter (Online Example):
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Int32? seed = null) {
List<T> buffer = source.ToList();
Random random = seed.HasValue ? new Random(seed.Value) : new Random();
Int32 count = buffer.Count;
for (Int32 i = 0; i < count; i++) {
Int32 j = random.Next(i, count);
yield return buffer[j];
buffer[j] = buffer[i];
}
}
Upvotes: 1
Reputation: 109547
You can use a standard shuffle algorithm, such as the one from this answer:
Suitably modified to add a seed parameter, it would look like this:
public static void Shuffle<T>(IList<T> list, int seed)
{
var rng = new Random(seed);
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;
}
}
Then to shuffle in a repeatable way, just specify the same seed for the shuffle for each repeated shuffle:
List<String> names = getAlphabeticallyOrderedNames();
int seed = 12345;
Shuffle(names, seed);
Upvotes: 5
Reputation: 3693
Try ordering by the hash value
var shuffled = names.OrderBy(n=>n.GetHashCode());
Upvotes: 0