LINQ donde vs takewhile


Quiero obtener una diferencia entre los métodos takewhile & where LINQ .Tengo los siguientes datos de MSDN .Pero no tenía sentido para mí

Where<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>) 

Filtra una secuencia de valores basada en un predicado.

TakeWhile<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>)

Devuelve elementos de una secuencia siempre que una condición especificada sea verdadera.

Todas las opiniones son bienvenidas.

 80
Author: Mohammed Thabet, 2011-02-17

6 answers

TakeWhile se detiene cuando la condición es falsa, Donde continúa y encuentra todos los elementos que coinciden con la condición

var intList = new int[] { 1, 2, 3, 4, 5, -1, -2 };
Console.WriteLine("Where");
foreach (var i in intList.Where(x => x <= 3))
    Console.WriteLine(i);
Console.WriteLine("TakeWhile");
foreach (var i in intList.TakeWhile(x => x <= 3))
    Console.WriteLine(i);

Da

Where
1
2
3
-1
-2
TakeWhile
1
2
3
 130
Author: Albin Sunnanbo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-17 16:37:32

Where puede examinar toda la secuencia buscando coincidencias.

Enumerable.Range(1, 10).Where(x => x % 2 == 1)
// 1, 3, 5, 7, 9

TakeWhile deja de mirar cuando se encuentra con el primer no-partido.

Enumerable.Range(1, 10).TakeWhile(x => x % 2 == 1)
// 1
 25
Author: Amy B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-15 17:26:14

Digamos que tienes un array que contiene [1, 3, 5, 7, 9, 0, 2, 4, 6, 8]. Ahora:

var whereTest = array.Where(i => i <= 5); volverá [1, 3, 5, 0, 2, 4].

var whileTest = array.TakeWhile(i => i <= 5); volverá [1, 3, 5].

 7
Author: Jim Mischel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-17 16:39:20

MSDN dice

Enumerable.TakeWhile Method

Devuelve elementos de una secuencia como siempre que una condición especificada sea verdadera, y luego se salta los elementos restantes.

Enumerable.Where

Filtra una secuencia de valores basada en predicado.

La diferencia es que Enumerable.TakeWhile omite los elementos restantes de la primera no coincidencia, ya sea que coincidan con la condición o no

 7
Author: naveen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-02-17 16:44:17

Si bien las respuestas existentes son correctas, ninguna de ellas señala por qué querría usar takeWhile si los resultados fueran los mismos: Rendimiento. Supongamos que tiene una lista ordenada con 2 mil millones de elementos en ella, y desea los que (probablemente 10 o 15 elementos) menos que un value dado. La cláusula Where examinará todos los 2 mil millones de elementos, mientras que takeWhile se detendrá tan pronto como encuentre un valor igual o mayor que su valor suministrado

 5
Author: jmoreno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-29 15:21:02

El orden de la secuencia pasada es absolutamente crítico con TakeWhile, que terminará tan pronto como un predicado devuelva false, mientras que Where continuará evaluando la secuencia más allá del primer valor false.

Un uso común para TakeWhile es durante la evaluación perezosa de enumerables grandes, costosos o incluso infinitos donde puede tener conocimiento adicional sobre el orden de la secuencia.

Por ejemplo, dada la secuencia:

IEnumerable<BigInteger> InfiniteSequence()
{
    BigInteger sequence = 0;
    while (true)
    {
        yield return sequence++;
    }
}

A .Where resultará en un bucle infinito tratando de evaluar parte de lo enumerable:

var result = InfiniteSequence()
    .Where(n => n < 100)
    .Count();

Considerando que a .TakeWhile, y armado con el conocimiento de que los enumerables es ascendente, permitirá evaluar la secuencia parcial:

var result = InfiniteSequence()
    .TakeWhile(n => n < 100)
    .Count();
 4
Author: StuartLC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-23 06:57:22