IEnumerable 的随机顺序

发布于 2025-01-06 22:15:18 字数 618 浏览 2 评论 0原文

我有一个 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 的结果输出到控制台两次,元素会再次被打乱。

您能建议如何保留这件制服吗?即,一旦我处理了该集合,此后它应该保持相同的方式。不过,我必须使用惰性求值,因为结果非常巨大。

I have got an IEnumerable collection as follows

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

I have to juggle the elements and create another collection in a random way which should result as follows:

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.

I have done this by the following means:

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

However the issue with this is that if I access result2 the elements in result2 gets shuffled again, i.e if I output the results of result2 to a console twice, the elements are juggled again.

Can you please advice how to keep this uniform. i.e once I juggle the collection, it should remain the same way thereafter. I have to use lazy evaluation though, since the results are very huge in size.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

当梦初醒 2025-01-13 22:15:18

您正在寻找随机播放算法

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

使用 Random 和 OrderBy 是一个好的洗牌算法吗?

洗牌所需的 IEnumerable 上的扩展方法


要回答您的问题“为什么又被打乱了吗?”,这是因为 OrderBy 的工作方式(延迟执行)。你可以尝试:

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

You are looking for a shuffle algorithm.

See following SO threads to provide nice extensions method to do the job:

Is using Random and OrderBy a good shuffle algorithm?

An extension method on IEnumerable needed for shuffling


To answer your question "why is that shuffled again?", it's because of how OrderBy works (lazy execution). You could try:

var result2 = result1.OrderBy(order=>random.Next()).ToList();
浪漫人生路 2025-01-13 22:15:18

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

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() ,这些不会改变。当您最终想要 result1 中的项目时,您可以使用随机数、OrderBy 随机数和 Select 结果来压缩项目。

只要 result1 中的项目顺序相同,orderedResult 中的结果每次都应该相同。

I see you require lazy evaluation for the results, if that is the case, what you can do is this:

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

By calling ToArray() on the random numbers, these will not change. When you finally desire the items in result1, you can zip the items with the random numbers, OrderBy the random number and Select the result.

As long as the items in result1 come in the same order, the result in orderedResult should be the same each time.

日记撕了你也走了 2025-01-13 22:15:18

您可以像这样使用 ToList()

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

You can use ToList() like this:

var result2 = result1.OrderBy(order=>random.Next()).ToList();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文