Dumbo
Dumbo

Reputation: 14122

Is there something like `continue` to bypass or skip an iteration of query in LINQ?

Take this example:

        int[] queryValues1 = new int[10] {0,1,2,3,4,5,6,7,8,9};
        int[] queryValues2 = new int[100]; // this is 0 to 100

        for (int i = 0; i < queryValues2.Length; i++)
        {
            queryValues2[i] = i;
        }

        var queryResult =
            from qRes1 in queryValues1
            from qRes2 in queryValues2
            where qRes1 * qRes2 == 12
            select new { qRes1, qRes2 };

        foreach (var result in queryResult)
        {
            textBox1.Text += result.qRes1 + " * " + result.qRes2 + " = 12" + Environment.NewLine;
        }

Obviously this code will result in:

1 * 12 = 12
2 * 6 = 12
3 * 4 = 12
4 * 3 = 12
6 * 2 = 12

But what I need is only the first 3 lines. That is I do not want if 2*6 = 12 the query checks if 6*2 is also 12. Is there a way to filter this in the LINQ query or I have to do it in the foreach loop afterward?

My question just is a sample to show what I mean. so I want to know the way of doing such thing no matter what is the type of object being linqed to!

Upvotes: 0

Views: 1717

Answers (3)

BLUEPIXY
BLUEPIXY

Reputation: 40145

TakeWhile(condition):Returns elements from a sequence as long as a specified condition is true, and then skips the remaining elements.

foreach (var result in queryResult.TakeWhile(x => x.qRes1 <= Math.Sqrt(12)))

Upvotes: 0

jasonp
jasonp

Reputation: 410

You could use .Distinct() and create your own IEqualityComparer that compares objects based on what 'equals' means in your case.

So, for your original example:

class PairSetEqualityComparer : IEqualityComparer<Tuple<int, int>>
    {
        public bool Equals(Tuple<int, int> x, Tuple<int, int> y)
        {
            return (x.Item1 == y.Item1 && x.Item2 == y.Item2) ||
                   (x.Item1 == y.Item2 && x.Item2 == y.Item1);
        }

        public int GetHashCode(Tuple<int, int> obj)
        {
            return obj.Item1*obj.Item2;
        }
    } 

And, you use it like this:

var queryResult =
            (from qRes1 in queryValues1
            from qRes2 in queryValues2
            where qRes1 * qRes2 == 12
            select new Tuple<int, int>(qRes1, qRes2)).Distinct(new PairSetEqualityComparer());

Upvotes: 2

Kevin Stricker
Kevin Stricker

Reputation: 17388

In general the simple solution would be more where conditions since the where clauses are what by definition cause LINQ to skip iterations:

var queryResult =
    from qRes1 in queryValues1
    from qRes2 in queryValues1
    where qRes1 * qRes2 == 12
    && qRes1 <= Math.Sqrt(12)
    select new { qRes1, qRes2 };

Upvotes: 4

Related Questions