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