Question

After answering this question I put together the following C# code just for fun:

public static IEnumerable<int> FibonacciTo(int max)
{     
    int m1 = 0;
    int m2 = 1;
    int r = 1;

    while (r <= max)
    {
       yield return r;

       r = m1 + m2;
       m1 = m2;
       m2 = r;
    }
}

foreach (int i in FibonacciTo(56).Where(n => n >= 24) )
{
   Console.WriteLine(i);
}

The problem is that I don't like needing to pass a max parameter to the function. Right now, if I don't use one the code will output the correct data but then appear to hang as the IEnumerable continues to work. How can I write this so that I could just use it like this:

foreach (int i in Fibonacci().Where(n => n >= 24 && n <= 56) )
{
   Console.WriteLine(i);
}
Was it helpful?

Solution

You need to use a combination of SkipWhile and TakeWhile instead.

foreach (int i in Fibonacci().SkipWhile(n => n < 24)
                             .TakeWhile(n => n <= 56))
{
   Console.WriteLine(i);
}

These are able to end loops depending on a condition; Where streams its input (filtering appropriately) until the input runs out (in your case, never).

OTHER TIPS

I don't think this is possible unless you write your own LINQ provider. In the example you gave you are using LINQ to Objects which will need to completely evaluate the IEnumerable before it can apply a filter to it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top