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
.