IEnumerable的随机顺序

Mik*_*ike 3 c# ienumerable c#-4.0

我有一个IEnumerable集合如下

var result1 = GetResult1() // Returns 2,4,5,6
Run Code Online (Sandbox Code Playgroud)

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

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.
Run Code Online (Sandbox Code Playgroud)

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

var result1 = GetResult1();
var random = new Random();
var result2 = result1.OrderBy(order=>random.Next());
Run Code Online (Sandbox Code Playgroud)

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

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

ken*_*n2k 5

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

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

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

改组所需的IEnumerable扩展方法


要回答你的问题"为什么会再次洗牌?",这是因为OrderBy工作原理(懒惰执行).你可以尝试:

var result2 = result1.OrderBy(order=>random.Next()).ToList();
Run Code Online (Sandbox Code Playgroud)


Luk*_*oid 3

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

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);
Run Code Online (Sandbox Code Playgroud)

通过调用ToArray()随机数,这些不会改变。当您最终想要 中的项目时result1,您可以使用随机数、OrderBy随机数和Select结果来压缩项目。

只要 in 中的项目result1按相同顺序出现,每次的结果orderedResult就应该相同。