对两个布尔值列表进行逻辑或

时间:2019-12-11 18:51:32

标签: c# linq boolean logical-operators

我有两个bool列表,两个列表的长度始终相同。假设这些是我的两个列表:

var list1 = new List<bool>() { true, false, true, false, false };
var list2 = new List<bool>() { true, true, true, false, true };

我想通过将逻辑OR运算符应用于任一列表中的每个对应索引来创建新列表。因此,如果我的两个列表都在上面,我的预期结果将是下面的。

  

true,true,true,false,true

现在,我可以通过使用for这样的循环轻松地做到这一点:

var result = new List<bool>();
for (int i = 0; i < list1.Count; i++)
{
    result.Add(list1[i] || list2[i]);
}

这非常好用,甚至不一定效率低下。但是在我的应用程序中,我有2个以上的列表,有时甚至有20个,并且我需要获取所有列表中的OR

考虑所有列表,有没有更简便的方法?

3 个答案:

答案 0 :(得分:3)

您可以尝试类似的事情

var result = list1.Zip(list2, (first, second) => first || second);

IEnumerable.Zip通过对两个源序列中的元素应用特定功能来生成结果序列,有关详细信息,请查看MSDN

答案 1 :(得分:3)

在评论Pavel Anikhouski的答案时,您提到了多个列表。我将使用Aggregate扩展方法来扩展该答案。

public static IEnumerable<bool> OrBooleanSequences(IEnumerable<IEnumerable<bool>> source)
{
    return source.Aggregate((a, b) => a.Zip(b, (x, y) => x || y));
}

只需将列表作为数组或其他可枚举形式传递,然后验证结果即可。

var list1 = new List<bool>() { true, false, true, false, false, false };
var list2 = new List<bool>() { true, true, true, false, true, false };
var list3 = new List<bool>() { false, true, false, true, true, false };

var result = ZipMultiple(new[] { list1, list2, list3 }).ToList();

编辑

根据@Theodor Zoulias的建议,我将上述方法重命名。我选择了OrBooleanSequences。不过,该名称是相当随意的,因此,如果您使用该名称,并且希望将其命名为对您而言更有意义的其他名称,那么您的权力就更大。

因此,这导致我将调用AggregateSequences的更通用的方法,它将是一个具有描述如何执行聚合的功能的高阶函数(resultSelector Zip超载)。

public static IEnumerable<TSource> AggregateSequences<TSource>(IEnumerable<IEnumerable<TSource>> source, Func<TSource, TSource, TSource> resultSelector)
{
    return source.Aggregate((a, b) => a.Zip(b, resultSelector));
}

...,您将把逻辑或运算作为lambda传递给它。

var result = AggregateSequences(new[] { list1, list2, list3 }, (x, y) => x || y).ToList();

这可以用于其他操作,例如对列表中的元素求和:

var list1 = new List<int>() { 1, 2, 3 };
var list2 = new List<int>() { 4, 5, 6 };
var list3 = new List<int>() { 7, 8, 9 };

var result = AggregateSequences(new[] { list1, list2, list3 }, (x, y) => x + y).ToList();

结果:

[ 12, 15, 18 ]

当然,此方法只是一种变体。 ZipAggregate可以合并多个重载。我不确定所有组合是否有意义,但我会将其留给读者练习。

答案 2 :(得分:2)

假设您有一个列表列表:

var listsOfLists = new List<IEnumerable<bool>>
{
    new List<bool>() { true, false, true, false, false },
    new List<bool>() { true, true, true, false, true },
    new List<bool>() { true, false, true, false, false },
    new List<bool>() { true, false, true, true, true }
};

使用Linq,您可以结合使用AggregateZip

var combinedResults = listsOfLists
    .Aggregate((a, b) => a
        .Zip(b, (aElement, bElement) => aElement || bElement)
     );

Zip将配对两个选定列表中的每个元素,并对这些元素对运行“或”运算符,从而为您提供一个新的布尔列表。该结果列表将在下一个汇总操作中使用。