I have a List<bool>
with lots of values. What is the most efficient way to check if every single item in the list equals false
?
sum(data) represents the addition of 1 and 0 with respective values of True(1) and False(0) in a list. In the case of all False sum is 0, and in the case of all True sum is equal to the length of the list. any sum value other than 0 & 1 means not all is False or True.
Python all() Function The all() function returns True if all items in an iterable are true, otherwise it returns False. If the iterable object is empty, the all() function also returns True.
An alternative approach is to use the logical OR (||) operator. To check if a value is of boolean type, check if the value is equal to false or equal to true , e.g. if (variable === true || variable === false) . Boolean values can only be true and false , so if either condition is met, the value has a type of boolean.
A boolean list ("blist") is a list that has no holes and contains only true and false . Boolean lists can be represented in an efficient compact form, see 22.5 for details. Boolean lists are lists and all operations for lists are therefore applicable to boolean lists.
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>
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With