Bool列表检查列表中的每个项目是否为false
我有一个List
有很多值。 检查列表中的每个项目是否等于false
的最有效方法是什么?
我同意使用IEnumerable.Any / All 。 但是,我不同意目前投票最多的答案(在撰写本文时这是错误的)以及Any vs All的一些相关评论。
以下操作在语义上是等效的 。 请注意,否定应用于内部,谓词和操作结果。
!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(..)
是false,因为是empty.All(..)
和上面的等价关系仍然有效。
此外, 两种forms都经过延迟评估,在LINQ To Objects中需要相同数量的评估; 在内部,对于序列实现,差异仅仅是否定对谓词和结果值的检查。
你可以使用Enumerable.Any
它会在第一场比赛中找到满足条件。 正如Habib正确地说更好地使用Any作为Enumerable.All将返回true为空列表bool。
!lst.Any(c=> c == true);
或者使用Enumerable.All
lst.All(c=> c == false);
一个明显更快的解决方案,这里没有提到,使用Contains
if (!myList.Contains(true)) // Great success - all values false!
从逻辑上讲,这种技术应该比IEnumerable.All
更快,因为它可以在第一次出现时返回true
。 我刚刚与IEnumerable.Any
了比较,它明显更快。 在我的测试IEnumerable.All
执行与IEnumerable.Any
相同,也许类似的算法用于引擎盖下的这两个function。 我还检查了IEnumerable.Exists
,它比IEnumerable.Any
和IEnumerable.All
表现更好,但仍然比Contains
慢。
在10000000个bool条目的列表中(我也尝试了0和1个条目,结果相似) ,我想出了以下指标:
通过任何 = 95ms经过
全部经过= 88ms
经过的存在= 27ms
经过包含 = 17ms
包含比任何快〜5.59倍 !
使用以下代码进行测试:
// setup initial vars var myList = new List(); 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 = {0}ms", timeAny); Console.WriteLine("Elapsed via All = {0}ms", timeAll); Console.WriteLine("Elapsed via Exists = {0}ms", timeExists); Console.WriteLine("Elapsed via Contains = {0}ms", timeContains); Console.WriteLine("Contains is ~{0}x faster than Any!", percentFaster);
请注意,这只适用于类型只能有两种状态的类型(即它不会处理> 2状态的变量,例如Nullable
)
您可以使用LINQ's
All
方法:
list.All(x => x == false);
如果它找到一个等于true
的值,它将立即返回false
。