Dmitry Petrov
Dmitry Petrov

Reputation: 1547

C# LINQ Zip: find at least one pair

I have two arrays and I'd like to know if some condition satisfy at least one pair from the lists.

Minimum reproducing code:

    var boxTypes = new string[] { "Banana", "Apple", "Apple", "Banana" };
    var boxSizes = new int[] { 31, 16, 35, 8 };

    int bigBoxSize = 20;
    bool hasBigAppleBox = 
        boxTypes.Zip(boxSizes,
                     (type, size) => (type == "Apple" && size >= bigBoxSize) ? 1 : 0)
                .Sum() > 0;

This code iterates through all pairs. But one pair is enough.

Any suggestion to improve this code?

Upvotes: 1

Views: 321

Answers (2)

Cameron
Cameron

Reputation: 2594

Short answer: Use Any(result => result > 1)

Long answer: Your use of Sum() is going to evaluate the entire collection, and using Any() will only evaluate until the first true condition is met.

Example:

boxTypes.Zip(boxSizes,
            (type, size) => (type == "Apple" && size >= bigBoxSize) ? 1 : 0)
            .Any(result => result == 1)

It's also worth noting that your (type == "Apple" && size >= bigBoxSize) ? 1 : 0 predicate can be simplified in this case to just be type == "Apple" && size >= bigBoxSize).

With this, your statement becomes:

boxTypes.Zip(boxSizes,
            (type, size) => type == "Apple" && size >= bigBoxSize)
            .Any()

Upvotes: 2

Yacoub Massad
Yacoub Massad

Reputation: 27861

You can do it like this:

bool hasBigAppleBox = 
    boxTypes.Zip(boxSizes,
                 (type, size) => type == "Apple" && size >= bigBoxSize)
            .Any(x => x);

Basically, for each pair, this code selects the result of the condition for that pair. This (the Zip method) returns an IEnumerable<bool>. Any(x => x) would return true when it meets the first true in the enumerable.

Upvotes: 3

Related Questions