Reputation: 415840
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);
}
Upvotes: 5
Views: 883
Reputation: 1500775
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).
Upvotes: 12
Reputation: 14114
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.
Upvotes: -2