C# 累积布尔值上的Linq聚合

C# 累积布尔值上的Linq聚合,c#,linq,C#,Linq,我有一个带字符串的列表: List<string> strList = new List<string>(); strList.Add("first"); strList.Add("second"); strList.Add("third"); strList.Add("fourth"); 但不幸的是我做错了什么 进一步解释: 我想为strList中的所有连续字符串对调用bool方法(string,string),并获取所有结果的布尔值&一种方法可能是创建这些对,然后

我有一个带字符串的列表:

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

strList.Add("first");
strList.Add("second");
strList.Add("third");
strList.Add("fourth");
但不幸的是我做错了什么

进一步解释:


我想为strList中的所有连续字符串对调用bool方法(string,string),并获取所有结果的布尔值&

一种方法可能是创建这些对,然后调用
Enumerable。all
查看其中是否有错误:

// 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));
但是,这是一个短循环(在遇到第一个
false
后将停止计算),并且在编辑之后,似乎要计算整个列表

在这种情况下,您可以在获得元组后使用(即具有不同类型累加器的重载)。从
true
开始,并使用布尔值
&

var finalResult = strList
    .Zip(strList.Skip(1), Tuple.Create)
    .Aggregate(true, (val, tuple) => Method(tuple.Item1, tuple.Item1) & val);
如果您的方法将接受一个
元组
,那么它的可读性可能会稍微好一些。

此方法使用一个
聚合
,并避免使用
Zip()
,但假设您以这样一种方式编码
方法
,以将初始空字符串作为种子元组的一部分来处理

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

您可以使用在工作中看到这一点。它不会处理列表中只有一个项目的情况,但接受的答案也不会。我想我们可以假设它会受到某处支票的保护

改进您的规格。“所以所有调用的返回值都是false”。但是您的第一次和第二次迭代返回true。@HaraldDutch:OP想对
strList
中所有连续的
string
对调用
bool方法(string,string)
,并获得所有结果的布尔值
&
。只是想澄清一下,您是否想短路(即在第一次
false
值之后停止计算),或计算到列表末尾并返回最终结果?使用linq进行这些相邻类型比较的不幸之处在于,实现很少发生短路
All
一旦发现错误就会停止,但直到您将整个集合压缩成成对后才会停止。@Chee'sBurgers:为什么您说它“很少”短路?恰恰相反,LINQ的所有方法都是惰性的,在第一个
false
结果之后不会创建元组(当然,在第一个示例中)。就像
对本身不会计算任何值一样。或者,例如,
pairs.First()
将只创建一个元组。必须小心使用
&&
,因为它会短路,而OP不希望这样。例如,您的答案在第一个
false
之后停止计算,因为
val.Item2
从该点开始就是
false
。交换订单将解决问题,但我想让OP避免这些问题。Oops错过了这一点。让我想知道OP到底想做什么。对不起,在我调试的最后一个linq问题示例中,我一定有一个
列表。Zip甚至可枚举。范围根据需要进行短路/评估。
        var result = strList.Aggregate(
            Tuple.Create("", true),
            (val, current) => Tuple.Create(current, val.Item2 & Method(val.Item1, current)),
            val => val.Item2);