使用 C# 6,我有一个按字母顺序排列的名称列表:
List<String> names = getAlphabeticallyOrderedNames();
我需要洗牌名称,但我希望每次都得到相同的结果。所以我不能使用:
List<String> shuffledNames = names.OrderBy(x => Guid.NewGuid());
然后我尝试了类似的东西:
List<String> shuffledNames = names.OrderBy(x => "d2fda3b5-4089-43f9-ba02-f68d138dee49");
或
List<String> shuffledNames = names.OrderBy(x => Int32.MaxValue);
但是名字没有洗牌...
我该如何解决这个问题?
您可以使用标准的随机播放算法,例如此答案中的算法:
适当修改以添加种子参数,它看起来像这样:
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;
}
}
然后,要以可重复的方式洗牌,只需为每个重复的洗牌指定相同的种子:
List<String> names = getAlphabeticallyOrderedNames();
int seed = 12345;
Shuffle(names, seed);
使用 Yield 并将 Seed 值作为参数的可枚举扩展(在线示例(:
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];
}
}
尝试按哈希值排序
var shuffled = names.OrderBy(n=>n.GetHashCode());