ohadinho
ohadinho

Reputation: 7144

Linq aggregate on accumulated bool values

I have a list with strings:

List<string> strList = new List<string>();

strList.Add("first");
strList.Add("second");
strList.Add("third");
strList.Add("fourth");

I need to send two strings on every iteration to some method that returns bool and finally tell what was the result.

For instance:

So return value from all calls is false (performing "&&" between those return values) .

I have to use LINQ so I've try to do something like:

strList.Aggregate<bool>((prev, current) => Method(prev,current));

but unfortunately I'm doing something wrong.

Further explanation:

I want to call bool Method(string, string) for all successive string pairs in strList and get the boolean && of all the results

Upvotes: 4

Views: 5462

Answers (2)

Kit
Kit

Reputation: 21729

This method uses a different overload of Aggregate and avoids the Zip(), but assumes you code Method in such a way to handle the initial empty string as parted of the seeded tuple.

        var result = strList.Aggregate(
            Tuple.Create("", true),
            (val, current) => Tuple.Create(current, val.Item2 & Method(val.Item1, current)),
            val => val.Item2);

You can see this at work using this .NET Fiddle. It does not handle a case of only 1 item in the list, but then, neither does the accepted answer. I guess we can assume that will be protected by a check somewhere.

Upvotes: 0

vgru
vgru

Reputation: 51274

One way might be to create the pairs, and then call Enumerable.All to see if any of them is false:

// create tuples
var pairs = strList
    .Zip(strList.Skip(1), Tuple.Create);

// check if all are true
var result = pairs.All(p => Method(p.Item1, p.Item2));

However, this is short-circuting (will stop evaluating after the first false is encountered), and after the edit, it seems you want to evaluate the whole list.

In that case, you can use Aggregate<Tuple<string>, bool> (i.e. the overload which has an accumulator of a different type) after you've got the tuples. Start with true, and use the boolean &:

var finalResult = strList
    .Zip(strList.Skip(1), Tuple.Create)
    .Aggregate(true, (val, tuple) => Method(tuple.Item1, tuple.Item1) & val);

If your method would accept a Tuple, it would perhaps be slightly more readable.

Upvotes: 7

Related Questions