2011-02-17 19 views
70

Quiero conseguir una diferencia entre takeWhile & donde los métodos de LINQ .I obtuvieron los siguientes datos de MSDN .Pero no tenía sentido para míLINQ donde vs takeWhile

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

Filtros una secuencia de valores basados 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.

Respuesta

121

TakeWhile se detiene cuando la condición es falsa, donde continúa y encontrar todos los elementos que cumplen 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 
24

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 buscar cuando se encuentra con el primer no-partido.

Enumerable.Range(1, 10).TakeWhile(x => x % 2 == 1) 
// 1 
+0

gracias. Ahora tiene sentido para mí :) –

6

Digamos que tiene una matriz que contiene [1, 3, 5, 7, 9, 0, 2, 4, 6, 8]. Ahora:

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

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

+0

Creo que whileTest devolverá solo 1 depende de @David B y @Albin Sunnanbo responde –

+0

No, devolverá elementos hasta que no se cumpla la condición. En este caso, 1, 3 y 5 cumplen la condición (son <= 5). –

+0

sí, lo siento amigo. Tiene razón, es mi error –

7

MSDN dice

Enumerable.TakeWhile Method

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

Enumerable.Where

filtra una secuencia de valores sobre la base de un predicado.

La diferencia es que Enumerable.TakeWhileOmite los elementos restantes de la primera no coincidencia si coinciden la condición o no

4

El orden de la secuencia pasado es absolutamente crítico con TakeWhile, que terminará como pronto como un predicado devuelve 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 diferida de enumerados grandes, caros o incluso infinitos, donde puede tener conocimiento adicional sobre el orden de la secuencia.

p. Ej. Dada la secuencia:

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

Un .Where dará lugar a un bucle infinito se trata de evaluar parte de la enumerables:

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

Mientras que un .TakeWhile, y armado con el conocimiento de que las enumerables es ascendente, se permiten que la secuencia parcial que se evaluará

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

Si bien las respuestas existentes son correctos, ninguno de ellos señalan por qué desea usar TakeWhile si los resultados serían los mismos: Rendimiento. Supongamos que tiene una lista ordenada con 2 mil millones de elementos, y quiere los que (probablemente 10 o 15 artículos) sean menos que un valor determinado. La cláusula Where examinará los 2 mil millones de elementos, mientras que TakeWhile se detendrá tan pronto como encuentre un valor igual o superior al valor suministrado