有没有办法从构建自身的方法中循环访问IEnumerable<T>正在构建的集合?yield returnIEnumerable
愚蠢的例子:
Random random = new Random();
IEnumerable<int> UniqueRandomIntegers(int n, int max)
{
while ([RETURN_VALUE].Count() < n)
{
int value = random.Next(max);
if (![RETURN_VALUE].Contains(value))
yield return value;
}
}
Run Code Online (Sandbox Code Playgroud)
这里是没有收藏正在建立.返回的序列是懒惰地评估的,除非调用者明确地将数据复制到另一个集合,否则它将在获取后立即消失.
如果你想确保独特性,你需要自己做.例如:
IEnumerable<int> UniqueRandomIntegers(int n, int max)
{
HashSet<int> returned = new HashSet<int>();
for (int i = 0; i < n; i++)
{
int candidate;
do
{
candidate = random.Next(max);
} while (returned.Contains(candidate));
yield return candidate;
returned.Add(candidate);
}
}
Run Code Online (Sandbox Code Playgroud)
唯一随机整数的另一种替代方法是构建max项目集合并对其进行洗牌,这仍然可以及时完成.这是在的情况下更高效max和n类似,但在的情况下效率低下(如你,直到你幸运地得到一个新的项目并不需要循环轮)max是非常大的,n是不是.
编辑:如评论中所述,您可以通过将for循环体更改为:
int candidate;
do
{
candidate = random.Next(max);
} while (!returned.Add(candidate))
yield return candidate;
Run Code Online (Sandbox Code Playgroud)
如果项目已存在于集合中,Add则使用将返回的事实false.