我有一个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的结果输出到控制台两次,那么元素会再次被混淆。
请告诉你如何保持这种制服。一旦我处理了这个收藏品,它就应该保持相同的状态。我必须使用懒惰的评估,因为结果非常大。
答案 0 :(得分:5)
您正在寻找随机播放算法。
请参阅以下SO线程以提供良好的扩展方法来完成工作:
Is using Random and OrderBy a good shuffle algorithm?
An extension method on IEnumerable needed for shuffling
要回答你的问题“为什么会再次洗牌?”,这是因为OrderBy
的工作方式(延迟执行)。你可以尝试:
var result2 = result1.OrderBy(order=>random.Next()).ToList();
答案 1 :(得分:1)
您可以像这样使用ToList()
:
var result2 = result1.OrderBy(order=>random.Next()).ToList();
答案 2 :(得分:1)
我发现你需要对结果进行延迟评估,如果是这种情况,你可以做的是:
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
中的结果每次都应该相同。