Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# - TakeWhile and SkipWhile not returning?

I have a class RekenReeks which returns numbers starting from 2, multiplied by 2. So {2,4,8,16,32,64}

Now I learned about the TakeWhile and SkipWhile methods as well as LINQ.

So I have created 3 variables which should store exactly the same but my Console.WriteLine only prints selection1 and not 2 and 3.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            RekenReeks reeks = new RekenReeks(2, n => n * 2);
            var selection = from i in reeks
                        where i > 10
                        && i < 1000
                        select i;

        var selection2 = reeks.TakeWhile(n => n < 1000 && n > 10);

        var selection3 = reeks.SkipWhile(n => n > 1000 && n < 10);

        foreach (int i in selection)
        {
            Console.WriteLine("selection1 {0}",i);
        }

        foreach (int i in selection2)
        {
            Console.WriteLine("selection2 {0}", i);
        }

        foreach (int i in selection3)
        {
            Console.WriteLine("selection3 {0}", i);
        }

        Console.ReadLine();
    }
}


public class RekenReeks : IEnumerable<int>
{
    Func<int, int> getNew;
    int number;
    public RekenReeks(int starton, Func<int, int> getNewThing)
    {
        getNew = getNewThing;
        number = starton;
    }

    public IEnumerator<int> GetEnumerator()
    {
        yield return number;
        for (; ; )
        {

            yield return getNew(number);
            number = getNew(number);

        }

    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }


}
}
like image 658
Ivar Reukers Avatar asked Jul 23 '26 13:07

Ivar Reukers


1 Answers

Your sequence is unlimited (theoretically). You assume too much. The functionality of your program cannot possibly know that your sequence is strictly monotonic increasing.

var selection = from i in reeks
                    where i > 10
                    && i < 1000
                    select i;

This will never stop. Because the where will always pull the next value, it does not know it's condition will be satisfied, it always has to check the next value.

    var selection2 = reeks.TakeWhile(n => n < 1000 && n > 10);

This will take values, while they are between 11 and 999. As your sequence starts with 2, it will stop right on the first value.

    var selection3 = reeks.SkipWhile(n => n > 1000 && n < 10);

This will skip values while they are between 11 and 999. As the first is 2, it will skip none and therefore yield all.

like image 116
nvoigt Avatar answered Jul 25 '26 04:07

nvoigt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!