Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Infinite IEnumerable in a foreach loop

Tags:

yield

c#

linq

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);
}
like image 226
Joel Coehoorn Avatar asked May 05 '09 19:05

Joel Coehoorn


1 Answers

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).

like image 173
Jon Skeet Avatar answered Nov 03 '22 02:11

Jon Skeet