IEnumerable的随机顺序

我有一个IEnumerable集合如下

var result1 = GetResult1() // Returns 2,4,5,6 

我必须以随机方式处理元素并创建另一个集合,其结果如下:

 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. 

我通过以下方式完成此操作:

 var result1 = GetResult1(); var random = new Random(); var result2 = result1.OrderBy(order=>random.Next()); 

然而,问题在于,如果我访问result2,result2中的元素会再次被洗牌,即如果我将result2的结果输出到控制台两次,则元素会再次变为juggled。

你能告诉我如何保持这种制服。 也就是说,一旦我处理了这个集合,它应该保持相同的方式。 我必须使用懒惰的评估,因为结果非常大。

我看到你需要对结果进行惰性评估,如果是这种情况,你可以做的是:

 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); 

通过对随机数调用ToArray() ,这些不会改变。 当您最终需要result的项目时,您可以使用随机数拉链项目, OrderBy随机数并Select结果。

只要result的项目顺序相同, orderedResult的结果orderedResult都应该相同。

您正在寻找一种随机播放算法

请参阅以下SO线程以提供良好的扩展方法来完成工作:

使用Random和OrderBy是一个很好的shuffle算法吗?

改组所需的IEnumerable扩展方法


要回答你的问题“为什么会再次洗牌?”,这是因为OrderBy工作原理(延迟执行)。 你可以尝试:

 var result2 = result1.OrderBy(order=>random.Next()).ToList(); 

您可以像这样使用ToList()

 var result2 = result1.OrderBy(order=>random.Next()).ToList();