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.

80
demandé sur Mohammed Thabet 2011-02-17 19:33:11

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
130
répondu Albin Sunnanbo 2011-02-17 16:37:32

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
25
répondu Amy B 2014-08-15 17:26:14

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].

7
répondu Jim Mischel 2011-02-17 16:39:20

MSDN dit

Enumerable.TakeWhile Method

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.

Enumerable.Where

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

7
répondu naveen 2011-02-17 16:44:17

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

5
répondu jmoreno 2015-10-29 15:21:02

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();
4
répondu StuartLC 2015-06-23 06:57:22