访问收益率收益

dav*_*v_i 0 c# generator

有没有办法从构建自身的方法中循环访问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)

Jon*_*eet 5

这里没有收藏正在建立.返回的序列是懒惰地评估的,除非调用者明确地将数据复制到另一个集合,否则它将在获取后立即消失.

如果你想确保独特性,你需要自己做.例如:

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项目集合并对其进行洗牌,这仍然可以及时完成.这是在的情况下更高效maxn类似,但在的情况下效率低下(如你,直到你幸运地得到一个新的项目并不需要循环轮)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.