LINQ où vs takewhile
Je veux obtenir une différence entre les méthodes takewhile et where LINQ .J'ai obtenu les données suivantes de MSDN .Mais cela n'avait pas de sens pour moi
Where<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>)
Filtre une séquence de valeurs basée sur un prédicat.
TakeWhile<TSource>(IEnumerable<TSource>, Func<TSource, Boolean>)
Retourne les éléments d'une séquence tant qu'une condition est vraie.
Toutes les opinions sont les bienvenues.
6 réponses
TakeWhile s'arrête lorsque la condition est fausse, où continue et trouve tous les éléments correspondant à la condition
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);
Donne
Where
1
2
3
-1
-2
TakeWhile
1
2
3
Where
peut examiner toute la séquence à la recherche de correspondances.
Enumerable.Range(1, 10).Where(x => x % 2 == 1)
// 1, 3, 5, 7, 9
TakeWhile
arrête de regarder quand il rencontre le premier non-match.
Enumerable.Range(1, 10).TakeWhile(x => x % 2 == 1)
// 1
Disons que vous avez un tableau qui contient [1, 3, 5, 7, 9, 0, 2, 4, 6, 8]
. Maintenant:
var whereTest = array.Where(i => i <= 5);
sera de retour [1, 3, 5, 0, 2, 4]
.
var whileTest = array.TakeWhile(i => i <= 5);
sera de retour [1, 3, 5]
.
MSDN dit
Renvoie des éléments d'une séquence comme tant qu'une condition spécifiée est vraie, et puis saute les éléments restants.
Filtre une séquence de valeurs basée sur prédicat.
La différence est que Enumerable.TakeWhile
ignore les éléments restants de la première non-match, si elles correspondent à la situation ou pas
Bien que les réponses existantes soient correctes, aucune d'entre elles ne signale Pourquoi vous voudriez utiliser TakeWhile si les résultats seraient les mêmes: Performance. Supposons que vous avez une liste ordonnée avec 2 milliards d'articles, et vous voulez ceux qui (probablement 10 ou 15 points) moins de un vallue. La clause Where examinera tous les 2 milliards d'articles, tandis que le TakeWhile s'arrêtera dès qu'il trouvera une valeur égale ou supérieure à votre valeur fournie
L'ordre de la séquence passée est absolument critique avec TakeWhile
, qui se terminera dès qu'un prédicat retournera false
, alors que Where
continuera à évaluer la séquence au-delà de la première valeur false
.
Un usage courant pour TakeWhile
est lors de l'évaluation paresseuse des énumérables volumineux, coûteux ou même infinis où vous pouvez avoir des connaissances supplémentaires sur l'ordre de la séquence.
Par exemple, étant donné la séquence:
IEnumerable<BigInteger> InfiniteSequence()
{
BigInteger sequence = 0;
while (true)
{
yield return sequence++;
}
}
Un .Where
entraînera une boucle infinie essayant d'évaluer une partie de l'énumérable:
var result = InfiniteSequence()
.Where(n => n < 100)
.Count();
Alors qu'un .TakeWhile
, et armé de la connaissance que les énumérables sont ascendants, permettra d'évaluer la séquence partielle:
var result = InfiniteSequence()
.TakeWhile(n => n < 100)
.Count();