Bool list check if every item in list is false

I agree with the use of IEnumerable.Any/All. However, I disagree with the currently most-voted answer (which was wrong at the time of writing this) and several of the associated comments of Any vs All.

These following operations are equivalent semantically. Note that the negations are applied both inside, on the predicate, and on the result of the operation.

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

Now, in this case we are thus looking for:

If it is not the case that there is any true value.

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

Or,

It is the case that every value is not true.

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

There is nothing special for empty lists the result is the same: e.g. !empty.Any(..) is false, as is empty.All(..) and the above equivalence relation remains valid.

In addition, both forms are lazily evaluated and require the same number of evaluations in LINQ To Objects; internally the difference, for a sequence implementation, is merely negating the check on the predicate and the result value.


You can use Enumerable.Any it will find satisfy the condition on first match. As Habib rightly said better to use Any as Enumerable.All would return true for an Empty list of bool.

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

OR use Enumerable.All

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

A significantly faster solution, not mentioned here, is using Contains

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

I have compared Contains against IEnumerable.Any and Contains returns faster. In my tests IEnumerable.All performed the same as IEnumerable.Any, perhaps a similar algorithm is used for both these functions under the hood. I also checked IEnumerable.Exists which performed better than IEnumerable.Any and IEnumerable.All, but was still slower than Contains.

Of a list of 10,000,000 bool entries (I also tried 0 and 1 entries, with similar results), I came up with the following metrics:

Elapsed via Any = 95ms

Elapsed via All = 88ms

Elapsed via Exists = 27ms

Elapsed via Contains = 17ms

Contains is ~5.59x faster than Any!

Tested with the following code:

// 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);


Note this will only work with types where type can only have two states (i.e. it won't work variables of >2 states, such as Nullable<bool>)


You can use LINQ's All method:

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

This will return false immediately if it finds a value that equals to true.

Tags:

C#

List

Boolean