400 votes

Le maintien de l'ordre avec LINQ

J'utilise LINQ to Objects instructions sur un tableau ordonné. Les opérations qui ne devrais-je pas faire pour être certain de l'ordre de la matrice n'est pas modifié?

722voto

David B Points 53123

J'ai examiné les méthodes de Système.Linq.Énumérable, en écartant tout ce qui est retourné non-IEnumerable résultats. J'ai vérifié les remarques de chacun, pour déterminer comment l'ordre de le résultat serait différent de commande de la source.

Préserve L'Ordre Absolument. Vous pouvez mapper un élément source par index d'un élément de résultat

  • AsEnumerable
  • Cast
  • Concat
  • Sélectionnez
  • ToArray
  • ToList

Préserve L'Ordre. Les éléments sont filtrés, mais pas re-commandé.

  • Sauf
  • Se croisent
  • OfType
  • Sauter
  • SkipWhile
  • Prendre
  • TakeWhile
  • Zip (nouvelle dans .net 4)

Détruit l'Ordre - nous ne savons pas dans quel ordre s'attendre à des résultats.

  • Distinctes
  • ToDictionary
  • ToLookup

Redéfinit l'Ordre Explicitement les utiliser pour modifier l'ordre de la raison

  • OrderBy
  • OrderByDescending
  • Inverse
  • ThenBy
  • ThenByDescending

Redéfinit Afin que les effets secondaires

  • GroupBy - Le IGrouping objets sont donné dans un ordre basé sur l'ordre des éléments dans la source qui a produit la première clé de chaque IGrouping. Éléments dans un groupement sont donné dans l'ordre où ils apparaissent dans la source.
  • GroupJoin - GroupJoin conserve l'ordre des éléments de l'extérieur, et pour chaque élément de l'extérieur, l'ordre des éléments correspondants de l'intérieur.
  • Rejoignez - conserve l'ordre des éléments de l'extérieur, et pour chacun de ces éléments, l'ordre des éléments correspondants de l'intérieur.
  • SelectMany - pour chaque élément de la source, le sélecteur est invoquée et une séquence de valeurs est retourné.
  • Union - Lorsque l'objet retourné par cette méthode est énuméré, l'Union énumère les premier et deuxième dans l'ordre et les rendements de chaque élément qui n'a pas déjà été donné.

38voto

Jon Skeet Points 692016

Êtes-vous en train de parler SQL, ou sur les tableaux? En d'autres termes, êtes-vous à l'aide de LINQ to SQL ou LINQ to Objects?

Le LINQ to Objects opérateurs n'ont pas réellement changer leur source de données d'origine - ils construire des séquences qui sont soutenus efficacement par la source de données. Les seules opérations qui modifient la commande sont OrderBy/OrderByDescending/ThenBy/ThenByDescending - et même alors, ceux qui sont stables aussi commandé des éléments. Bien sûr, beaucoup d'opérations va filtrer certains éléments, mais les éléments qui sont retournés devront être dans le même ordre.

Si vous convertir à une autre structure de données, par exemple avec ToLookup ou ToDictionary, je ne crois pas que l'ordre est conservé à ce point - mais c'est un peu différent de toute façon. (L'ordre des valeurs de la cartographie à la même clé est conservée pour des recherches bien, je crois.)

8voto

Marc Gravell Points 482669

Si vous travaillez sur un tableau, il semble que vous êtes à l'aide de LINQ-to-Objets, pas SQL; pouvez-vous le confirmer? La plupart des LINQ opérations ne pas re-commander quoi que ce soit (la sortie sera dans le même ordre que celui de l'entrée) - il ne faut pas appliquer un autre type (OrderBy[Descendant]/ThenBy[Descendant]).

[edit: comme Jon mettre plus clairement; LINQ crée généralement une nouvelle séquence, en laissant les données d'origine seul]

Notez qu'en poussant les données en Dictionary<,> (ToDictionary) va brouiller les données, comme dictionnaire ne pas respecter tout ordre de tri.

Mais la plupart des choses en commun (Select, where, Sauter, Prendre) doit être fine.

5voto

Curtis Yallop Points 639

J'ai trouvé une super réponse à une question similaire, les renvois à la documentation officielle. Pour le citer:

Pour Enumerable méthodes (LINQ to Objects, qui s'applique à l' List<T>), vous pouvez compter sur l'ordre des éléments retournés par Select, Whereou GroupBy. Ce n'est pas le cas pour les choses qui sont par nature non ordonnée comme ToDictionary ou Distinct.

De Énumérable.GroupBy de la documentation:

L' IGrouping<TKey, TElement> des objets sont donné dans un ordre basé sur l'ordre des éléments dans la source qui a produit la première clé de chaque IGrouping<TKey, TElement>. Éléments dans un groupement sont donné dans l'ordre où ils apparaissent dans source.

Ce n'est pas nécessairement vrai pour l' IQueryable les méthodes d'extension (d'autres fournisseurs LINQ).

Source: Faire de LINQ Énumérable Méthodes de Maintenir l'Ordre Relatif des Éléments?

2voto

leppie Points 67289

Tout le "groupe" ou "trier par" va peut-être changer l'ordre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X