处理大型数据集时,从给定集合中获取特定大小的随机打乱集合变为至关重要的。这通常出现在涉及随机选择或抽样的场景中。让我们探索一个基于 LINQ 的最佳解决方案来解决此问题。
Fisher-Yates-Durstenfeld 洗牌算法提供了一种高效可靠的随机洗牌方法。在这种情况下,目标是从“N”个元素的集合中生成大小为“n”的随机子集,其中“n”小于或等于“N”。
实现此算法使用 LINQ,我们可以利用封装 shuffle 操作的扩展方法。以下代码片段提供了一个全面的实现:
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng) { if (source == null) throw new ArgumentNullException(nameof(source)); if (rng == null) throw new ArgumentNullException(nameof(rng)); return source.ShuffleIterator(rng); } private static IEnumerable<T> ShuffleIterator<T>( this IEnumerable<T> source, Random rng) { var buffer = source.ToList(); for (int i = 0; i < buffer.Count; i++) { int j = rng.Next(i, buffer.Count); yield return buffer[j]; buffer[j] = buffer[i]; } }
在此实现中,Shuffle 扩展方法接受输入序列源和名为 rng 的 Random 实例。它根据输入序列创建一个缓冲区列表并迭代它,随机选择元素。所选元素作为迭代器返回,保留随机排序。
要使用此扩展方法,只需将 .Shuffle() 附加到输入序列,然后附加 .Take(n),其中 n 表示所需的大小已打乱顺序的子集合。例如:
var randomItems = yourCollection.Shuffle().Take(n);
这种基于 Linq 的方法提供了一种简洁高效的解决方案,用于随机洗牌并从给定集合中获取任意大小的子集合。它特别适合需要真正随机化的场景。
以上是如何使用 LINQ 随机打乱集合的子集?的详细内容。更多信息请关注PHP中文网其他相关文章!