Verifique si todos los elementos de la lista son falsos

Tengo una List con muchos valores. ¿Cuál es la forma más eficiente de verificar si cada elemento de la lista es false ?

Estoy de acuerdo con el uso de IEnumerable.Any / All . Sin embargo, no estoy de acuerdo con la respuesta más votada actualmente (que estaba equivocada en el momento de escribir esto) y con varios de los comentarios asociados de Any vs All.

Estas siguientes operaciones son equivalentes semánticamente. Tenga en cuenta que las negaciones se aplican tanto en el interior, como en el predicado y en el resultado de la operación.

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

Ahora, en este caso estamos buscando:

Si no es así, hay algún valor verdadero.

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

O ,

Es el caso que todo valor no es cierto.

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

No hay nada especial para las listas vacías, el resultado es el mismo: por ejemplo !empty.Any(..) es falso, como está empty.All(..) y la relación de equivalencia anterior sigue siendo válida.

Además, ambos formularios se evalúan perezosamente y requieren el mismo número de evaluaciones en LINQ To Objects ; internamente, la diferencia, para una implementación de secuencia, es simplemente negar la verificación del predicado y el valor del resultado.

Puede usar Enumerable.Any . Enumerable.Any que encuentre satisfará la condición en la primera coincidencia. Como Habib dijo correctamente que es mejor usar Cualquiera como Enumerable. Todos devolverían verdadero para una lista vacía de bool.

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

O use Enumerable.Todo

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

Una solución significativamente más rápida, no mencionada aquí, es usar Contains

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

Lógicamente, esta técnica debería ser más rápida que IEnumerable.All , ya que puede regresar temprano en la primera aparición de true . Acabo de comparar con IEnumerable.Any y es significativamente más rápido. En mis pruebas, IEnumerable.All lo mismo que IEnumerable.Any , tal vez se use un algoritmo similar para estas dos funciones bajo el capó. También verifiqué IEnumerable.Exists que obtuvieron mejores resultados que IEnumerable.Any y IEnumerable.All , pero aún eran más lentos que Contains .

De una lista de 10000000 entradas bool (también probé 0 y 1 entradas, con resultados similares) , obtuve las siguientes métricas:

Transcurrió a través de Any = 95ms

Transcurrió a través de todos = 88 ms

Transcurrió a través de Exist = 27ms

Transcurrido a través de Contiene = 17 ms

Contiene es ~ 5.59x más rápido que Any!

Probado con el siguiente código:

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


Tenga en cuenta que esto solo funcionará con tipos donde el tipo solo puede tener dos estados (es decir, no funcionará con variables de> 2 estados, como Nullable )

Puedes usar LINQ's método All LINQ's :

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

Esto devolverá false inmediatamente si encuentra un valor que es igual a true .