Filter over IEnumerable ... .Where?
本文关键字:Where IEnumerable over Filter | 更新日期: 2023-09-27 18:18:27
我编写了一个函数来生成奇数:
static IEnumerable<int> OddNumbers()
{
int n = 1;
while (true)
yield return 1 + 2 * (n++ - 1);
}
我如何浏览和筛选这个列表?我试图删除某个数字factor
的所有倍数,我这样写:
using (var oddNumbers = OddNumbers().GetEnumerator())
{
oddNumbers.MoveNext();
int factor = oddNumbers.Current;
yield return factor;
oddNumbers = oddNumbers.Where(x => x % factor != 0);
}
但是我被告知
The type arguments for method `System.Linq.Enumerable.Where<TSource>(
this System.Collections.Generic.IEnumerable<TSource>,
System.Func<TSource,bool>)' cannot be inferred from the usage.
Try specifying the type arguments explicitly`
根据我的理解,不需要直接访问枚举数,可以使用Linq单独完成,如下所示:
var FilteredNumbers = OddNumbers().Where(x => x % factor != 0);
您可以使用Linq:
// Initial generator
static IEnumerable<int> OddNumbers() {
for (int n = 1; ; n += 2) // for loop is far better than while here
yield return n;
}
...
var result = OddNumbers()
.Where(x => x % factor ! = 0);
或修改生成器本身:
static IEnumerable<int> OddNumbersAdvanced(int factorToExclude = int.MinValue) {
for (int n = 1; ; n += 2)
if (n % factorToExclude != 0)
yield return n;
}
...
var result = OddNumbersAdvanced(factor);
通过使用foreach
循环:
foreach (int item in result) {
//TODO: put relevant code here; do not forget to break the loop
}
由于需要生成幸运数字序列,因此我编写了一些代码来使用迭代器完成此操作。注意,这样做的效率非常低,但希望你这样做只是为了好玩或为了学习
static IEnumerable<int> LuckyNumbers(IEnumerable<int> all = null, int n = 2, int step = 0) {
if (step == 0) {
all = Enumerable.Range(1, int.MaxValue); // start with all numbers
yield return 1;
step++;
}
// apply a filter for current "n" (starting with 2)
var filtered = Filtered(all, n);
// get next item from the sequence (skip items first, because this sequence represents whole lucky number sequence, starting from 1)
var current = filtered.Skip(step).First();
yield return current;
step++;
// now recursive call back into LuckyNumber
foreach (var other in LuckyNumbers(filtered, current, step)) {
yield return other;
}
}
static IEnumerable<int> Filtered(IEnumerable<int> previous, int n) {
// filter out each n-th item
return previous.Where((x, i) => (i + 1)%n != 0);
}
像这样使用:
foreach (var next in LuckyNumbers().Take(10)) {
Console.WriteLine(next);
}