是否有办法在构建IEnumerable<T>
本身的方法中循环访问由yield return
构建的IEnumerable
集合?
愚蠢的例子:
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;
}
}
答案 0 :(得分: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);
}
}
唯一随机整数的另一种替代方法是构建max
项的集合并对其进行洗牌,这仍然可以及时完成。在max
和n
相似的情况下(因为您不需要循环直到您有幸获得新项目),这会更有效,但在{ {1}}非常大且max
不是。
编辑:如评论中所述,您可以通过将n
循环的正文更改为:
for
如果项目中已存在该项目,int candidate;
do
{
candidate = random.Next(max);
} while (!returned.Add(candidate))
yield return candidate;
将返回Add
这一事实。