tofana
tofana

Reputation: 83

Why is this yield break not breaking the loop?

I wrote a method that takes as input a sequence (it can also be an infinite sequence) and an integer count and returns a new sequence that contains count elements taken from the input sequence, that are in positions which are prime numbers. For example, if I have a sequence {5,13,84,10,2,6} and count = 3, the result sequence is {84,10,6}.

The class I wrote:

public static class PrimeMethod
{
    public static IEnumerable<T> TakePrime<T>(this IEnumerable<T> s, int count)
    {
        var result = new List<T>();
        if (s == null)
            throw new ArgumentNullException();
        if (count <= 0)
            throw new ArgumentOutOfRangeException();
        int x = 0;
        int y = 0; 
        foreach (var i in s)
        {
            if (checkIfPrime(x) && y < count)
            {
                result.Add(i);
                y++;
            }
          
            x++;
        }
        
        return result;
    }

    public static bool checkIfPrime(int num)
    {
        if (num == 0 || num == 1)
            return false;
        bool flag = false;
        for (int i = 2; i < num; i++)
            if (num % i == 0)
            {
                flag = true;
                break;
            }

        if (!flag)
            return true;
        return false;
    }
}

Now I have to write a parameterized test that takes as input a sequence from 0 to infinite and a size integer. The test must make sure that the size of the resulting list is equal to the parameter size.

I wrote this:

[TestCase(7)]
[TestCase(182)]
public void Check_Size(int size)
{
        var list = List_Integers(size);
        var result = list.TakePrime(size);
        Assert.That(()=>result.Count(),Is.EqualTo(size));
}

public IEnumerable<int> List_Integers(int size)
{
        var i = 0;
        var list = new List<int>();
        while(true)
        {
            var j = i;
            i++;
            list.Add(j);
            if (list.TakePrime(size).Count() > size)
               yield break;
            yield return j;
        }
}

Although I used a yield break the test never stops. Why is this not working?

UPDATE: I realized my mistake and I changed List_Integers to this:

public IEnumerable<int> List_Integers(int size)
    {
        var i = 0;
        var list = new List<int>();
        var incr = size+1;
        while(true)
        {
            var j = i;
            i++;
            list.Add(j);
            if (list.TakePrime(size).Count() >= incr)
                yield break;
            yield return j;
        }
    }

It's still not working and I don't understand why.

Upvotes: 0

Views: 168

Answers (2)

tofana
tofana

Reputation: 83

I found the solution which is this:

[TestCase(7)]
    [TestCase(182)]
    public void Check_Size(int size)
    {
        var incr = size + 1;
        var list = List_Integers(incr);
        var result = list.TakePrime(size);
        Assert.That(()=>result.Count(),Is.EqualTo(size));
    }

    public IEnumerable<int> List_Integers(int size)
    {
        var i = 0;
        var list = new List<int>();
       
        while(true)
        {
            var j = i;
            i++;
            list.Add(j);
            if (list.TakePrime(size).Count() >= size)
                yield break;
            yield return j;
        }
    }

Upvotes: 0

Ren&#233; Vogt
Ren&#233; Vogt

Reputation: 43906

You call

list.TakePrime(size)

Which (as you described and implemented yourself) will return a maximum of size primes. Hence it will never be greater than size.

Upvotes: 4

Related Questions