过滤IEnumerable ......。在哪里?

时间:2016-11-17 11:36:59

标签: c# generator ienumerable

我做了一个生成奇数的函数:

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`

3 个答案:

答案 0 :(得分:3)

根据我的理解,不需要直接访问枚举器,可以单独使用Linq完成,如下所示。

var FilteredNumbers = OddNumbers().Where(x => x % factor != 0);

答案 1 :(得分:1)

您可以使用 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
  }

答案 2 :(得分:0)

因为您需要生成幸运数字序列,所以这里是我用迭代器编写的一些代码。请注意,这样做效率非常低,但希望您这样做只是为了娱乐或学习

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);
}