【发布时间】:2020-05-22 08:38:18
【问题描述】:
我想从泛型类型数组中选择一组随机值(比如说 2 个值)。我设法实现了它,但出于某种原因,它有时会返回重复的数组,例如:[20.33, 20.33] 或 [32, 32] 或 ["Rugby", "Rugby"]。知道如何解决这个问题吗?
请注意,我是从 json 对象中获取此数组的,因此使用的是 Newtonsoft.Json JArray。
var arr = [ 0.4, 20.33, 76.01, 47.3, 23.78];
//or
var arr = [ 32, 68, 89, 27, 93];
// or
var arr = [ "Football", "Rugby", "Cricket", "Tennis", "Basketball"];
var count = 2;
var item = new JArray();
foreach (var m in Enumerable.Range(0, count).Select(i => arr[new Random().Next(arr.Count())]))
{
if (!item.Contains(m))
{
item.Add(m);
}
}
【问题讨论】:
-
“最佳”方法取决于数组中有多少值以及您要选择多少。如果它只有几个,那么您可以制作一个数组的副本并将其打乱(或等效)并从中获取前 N 个值。如果数组中有很多项,而您只想要其中的几个,则有更好的方法。
-
另请注意,您正在为每次迭代初始化 Random。这可能会增加重复的机会,因为 Random 是使用基于系统时钟的相同种子值初始化的。更好的方法是初始化 Random 一次并重用实例
-
@AnuViswan 对于 .Net Framework 确实如此 - 但请注意,对于 .Net Core 3.x,该特定问题已得到修复。但即使使用 .Net Core,我也同意 OP 应该在循环外创建 Random!
-
旁注:如果是
asp.net,我们应该注意线程安全(Random不是线程安全的,这就是为什么天真static Random s_Random = new Random();不是出路)。 devblogs.microsoft.com/pfxteam/… -
除了线程安全问题之外,循环中还有一个根本性的缺陷。它只迭代
count次,但如果其中一项因已在输出数组中而被拒绝,则循环将在添加正确数量的项之前终止。
标签: c# asp.net arrays .net json