【发布时间】:2017-02-11 00:21:43
【问题描述】:
我对编程还很陌生,我一直在尝试编写一些随机函数。
我编写了下面的函数,它基于eratosthenes sieve 松散地工作。不过,最初,我在使用 updatedEntries IEnumerable 时遇到了问题。
updatedEntites 有点填充(与我收集的延迟执行有关 - 在调试模式下,“当前”为空,但结果视图包含相关项目)但是当 RemoveWhere 应用于oddPrimesAndMultiples 时,updatedEntries 中的项目消失了即使我不明白为什么它们仍应链接到oddPrimesAndMultiples 中的项目。 (当然,我可能完全误解了正在发生的事情,问题可能完全是另外一回事!)
如果我将 updatedEntries 更改为 List 而不是 IEnumerable 则不会出现问题,并且我现在实际上已经重写了该语句而不使用 LINQ 来(可能?)更好地利用我正在使用的事实 SortedSet 反正...但我仍然想知道为什么会出现这个问题!
这是我的代码:
public static IEnumerable<int> QuickPrimes()
{
int firstPrime = 2;
int firstOddPrime = 3;
int currentValue = firstOddPrime;
int currentMinimumMultiple;
SortedSet<Tuple<int, int>> oddPrimesAndMultiples = new SortedSet<Tuple<int, int>>() { new Tuple<int, int> (firstOddPrime, firstOddPrime) };
IEnumerable<Tuple<int, int>> updatedEntries;
yield return firstPrime;
yield return firstOddPrime;
while (true)
{
currentMinimumMultiple = oddPrimesAndMultiples.First().Item1;
while (currentValue < currentMinimumMultiple)
{
yield return currentValue;
oddPrimesAndMultiples.Add(new Tuple<int, int> (currentValue * 3, currentValue));
currentValue += 2;
}
updatedEntries = oddPrimesAndMultiples.Where(tuple => tuple.Item1 == currentMinimumMultiple)
.Select(t => new Tuple<int, int>(t.Item1 + 2 * t.Item2, t.Item2));
oddPrimesAndMultiples.RemoveWhere(t => t.Item1 == currentMinimumMultiple);
oddPrimesAndMultiples.UnionWith(updatedEntries);
currentValue += 2;
}
}
以及我正在测试该功能的主要位置:
static void Main(string[] args)
{
foreach(int prime in Problems.QuickPrimes())
{
Console.WriteLine(prime);
if (prime > 20) return;
}
}
非常感谢!
【问题讨论】:
-
一个 IEnumerable,使用 yield 关键字确实可以提供非常不同的结果。明智地使用它。
-
让我看看我是否理解这一点,您的代码现在可以正常工作,但以前不是因为您没有对 updatedEntries 分配进行“.ToList()”调用,对吗?
-
您能提供minimal reproducible example的问题吗?目前的帖子甚至不清楚代码是否存在您正在谈论的问题。
-
@Fredy Treboux 和 Alexei - 抱歉,updatedEntries 上的 .ToList() 不应该存在 - 我从更正的代码中粘贴代码时忘记删除它(我只是更改了updatedEntries 从 List 返回到 IEnumerable!)如果没有 ToList() 调用,则会发生 InvalidOperation 错误,因为正如我上面写的那样,这些项目已从 updatedEntries 中删除,然后这意味着oddPrimesAndMultiples 也是导致错误的条目,当我尝试首先调用它时!根据需要更新问题。
-
请解释一个你观察到的基本例子,我觉得你的问题很难掌握。
标签: c# linq ienumerable