Bool列表检查列表中的每个项目是否为false

时间:2014-03-24 19:01:14

标签: c# list boolean

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

4 个答案:

答案 0 :(得分:36)

你可以使用Enumerable.Any它会在第一场比赛中找到满足条件。正如Habib正确地说更好地使用Any作为Enumerable.All将返回true为空列表bool。

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

或使用Enumerable.All

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

答案 1 :(得分:17)

我同意使用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(..)是错误的,empty.All(..)也是如此,上述等价关系仍然有效。

此外,两个表单都经过延迟评估,需要在LINQ To Objects中进行相同数量的评估。在内部,对于序列实现,差异仅仅是否定对谓词和结果值的检查。

答案 2 :(得分:5)

使用 Contains

的一种明显更快的解决方案(此处未提及)
if (!myList.Contains(true))
    // Great success - all values false! 

我将ContainsIEnumerable.Any进行了比较,而Contains的返回速度更快。在我的测试中,IEnumerable.AllIEnumerable.Any的执行方式相同,也许在幕后为这两个功能使用了类似的算法。我还检查了IEnumerable.Exists,它们的性能优于IEnumerable.AnyIEnumerable.All,但仍然比Contains慢。

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

  

通过任何 = 95ms

     

经过全部= 88毫秒

     

已存在= 27毫秒

     

通过包含 = 17ms

     

包含的内容比任何内容都要快〜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 = {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<bool>

答案 3 :(得分:2)

您可以使用LINQ's All方法:

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

如果找到的值等于false,则会立即返回true