布尔列表检查列表中的每个项目是不是为假

Posted

技术标签:

【中文标题】布尔列表检查列表中的每个项目是不是为假【英文标题】:Bool list check if every item in list is false布尔列表检查列表中的每个项目是否为假 【发布时间】:2014-05-02 08:00:56 【问题描述】:

我有一个 List<bool> 有很多值。检查列表中的每一项是否等于false 的最有效方法是什么?

【问题讨论】:

【参考方案1】:

你可以使用LINQ'sAll方法:

list.All(x => x == false);

如果找到等于true 的值,它将立即返回false

【讨论】:

如果列表不是布尔值而是包含布尔值的类,有没有办法执行此操作? @RyanN1220 lambda 变量“x”代表这里的对象。所以您只需要更改条件x.SomeBoolProperty == false!x.SomeBoolProperty【参考方案2】:

您可以使用Enumerable.Any 它会在第一次匹配时找到满足条件。正如 Habib 所说的那样,最好将 Any 用作 Enumerable。对于 Empty 的 bool 列表,All 将返回 true。

!lst.Any(c=> c == true);

或使用Enumerable.All

lst.All(c=> c == false);

【讨论】:

+1,最好使用Any,因为Enumerable.All 将返回true 以获得一个空的布尔列表。 +1 这比 All() 执行得更好,因为它总是迭代整个列表;当它找到一个时它会停止 @AdrianCarneiro 嗯..?这对我来说没有意义。两者都很懒惰,在这种情况下需要查看相同数量的元素。 @user2864740, negated 只是为 Any 提供 bool 值的一种简单方式,考虑以下代码:List<bool> list = new List<bool>(); var b1 = list.All(r => r == false); var b2 = list.Any(r => r == false);,现在 b1 将是 trueb2是假的。只是Enumerable.All 在空列表上的行为不同。 显然列表包含一些项目。这两个语句不一样。如果有任何项目等于true,则首先返回true,如果所有项目都等于@987654337,则返回true @.您需要在第一条语句上使用否定运算符。【参考方案3】:

我同意使用IEnumerable.Any/All。但是,我不同意当前投票最多的答案(在撰写本文时这是错误的)以及 Any vs All 的几个相关 cmet。

以下这些操作在语义上是等价的。请注意,否定应用在谓词内部和运算结果上。

!l.Any(x => f(x))
l.All(x => !f(x))

现在,在这种情况下,我们正在寻找:

如果是则有任何真值。

!l.Any(x => x)  // f(x) = x == true

或者

每个值都是为真。

l.All(x => !x)  // f'(x) = !f(x) = !(x == true)

空列表没有什么特别的,结果是一样的:例如!empty.Any(..) 是假的,empty.All(..) 也是假的,上面的等价关系仍然有效。

另外,两种表单都是惰性求值的,需要LINQ To Objects中相同的求值次数;在内部,对于序列实现而言,差异只是否定了对谓词和结果值的检查。

【讨论】:

如果列表不是布尔值而是包含布尔值的类,有没有办法执行此操作? @RyanN1220 是的。 LINQ 的 IEnumerable 在这方面是灵活的,因为在许多情况下都接受一个函数(例如,某些提供程序有限制,例如 LINQ-to-EF)。 All/Any 函数采用可选的Func<T, bool>。在上面,f(x) 是一个“一些代码”(和/或一个函数),它接受 x 并返回一个布尔值。例如,给定var a = new [] Tuple.Create(1, true), Tuple.Create(1, false) ,则a.Any(x => x.Item2) 为真,a.All(x => x.Item2) 为假。【参考方案4】:

这里没有提到的一个明显更快的解决方案是使用 Contains

if (!myList.Contains(true))
    // Great success - all values false! 

我将ContainsIEnumerable.Any 进行了比较,Contains 的返回速度更快。在我的测试中,IEnumerable.All 的性能与IEnumerable.Any 相同,可能在后台对这两个功能使用了类似的算法。我还检查了IEnumerable.Exists,它的性能优于IEnumerable.AnyIEnumerable.All,但仍然比Contains 慢。

在 10,000,000 个布尔条目列表中(我也尝试了 0 和 1 个条目,结果相似),我得出了以下指标:

经过任何 = 95ms

全部经过 = 88 毫秒

经过 Exists = 27ms

经过包含 = 17ms

Contains 比 Any 快约 5.59 倍

用以下代码测试:

// setup initial vars
var myList = new List<bool>();
for (int x = 0; x < 10000000; x++)
    myList.Add(false);  

var containsAllFalse = false;
Stopwatch sw = new Stopwatch();

// start test
sw.Start();
containsAllFalse = !myList.Any(x => x);
sw.Stop();

// get result for Any
var timeAny = sw.ElapsedMilliseconds;

// reset variable state (just in case it affects anything)
containsAllFalse = false;   

// start test 2
sw.Restart();
containsAllFalse = myList.All(x => x == false);
sw.Stop();

// get result for All
var timeAll = sw.ElapsedMilliseconds;

// reset variable state (just in case it affects anything)
containsAllFalse = false;   

// start test 3
sw.Restart();
containsAllFalse = !myList.Exists(x => x == true);
sw.Stop();

// get result for All
var timeExists = sw.ElapsedMilliseconds;

// reset variable state (just in case it affects anything)
containsAllFalse = false;   

// start test 4
sw.Restart();   
containsAllFalse = !myList.Contains(true);          
sw.Stop();

// get result from Contains
var timeContains = sw.ElapsedMilliseconds;

// print results
var percentFaster = Math.Round((double)timeAny / timeContains, 2);
Console.WriteLine("Elapsed via Any = 0ms", timeAny);
Console.WriteLine("Elapsed via All = 0ms", timeAll);
Console.WriteLine("Elapsed via Exists = 0ms", timeExists);
Console.WriteLine("Elapsed via Contains = 0ms", timeContains);
Console.WriteLine("Contains is ~0x faster than Any!", percentFaster);


请注意,这仅适用于类型只能具有两种状态的类型(即它不适用于 >2 种状态的变量,例如 Nullable&lt;bool&gt;

【讨论】:

不错的性能比较。在有许多解决方案的地方,性能优先。 如果列表不是布尔值而是包含布尔值的类,有没有办法执行此操作? “..因为它可以在第一次出现 true.. 时提前返回。”AllAny 都可以(并且确实如此)。虽然Contains 可能更快,但由于提前终止而不是更快。检查.NET Reference Source's IEnumerable.All 中的实现,正如我所料,它是惰性的,不会强制评估整个序列。 @user2864740 好点 - 谢谢!我将编辑 OP 以反映这一点。

以上是关于布尔列表检查列表中的每个项目是不是为假的主要内容,如果未能解决你的问题,请参考以下文章

如何测试“int”类型列表中的每个项目是不是?

此选项列表是不是可以接受数据库中的布尔标志?

Python - 有效地检查列表中的每个项目与其他项目

检查列表中的所有项目是不是相同

检查列表框中的项目是不是已存在于许多其他列表框中?

检查列表中的项目以查看它们是不是彼此相邻