Dans LINQ, les projections d’un IOrderedEnumerable préservent-elles l’ordre?

Si j’ai un IOrderedEnumberable , je le sortinge puis je fais une requête en projection …

l’ordre est-il préservé dans la projection?

Par exemple, ce scénario fonctionne-t-il?

 IOrderedEnumberable allCarsOrderedFastestToSlowest = GetAllCars() .OrderByDescending(car=>car.TopSpeed); var top3FastestCarManufacturers = allCarsOrderedFastestToSlowest .Select(car=>car.Manufacturer) .Distinct() .Take(3); 

Le nom de la variable top3FastestCarManufacturerstop3FastestCarManufacturers la signification de ce qui s’est réellement passé dans le code?

La documentation de la méthode Distinct n’indique pas si l’ordre est préservé ou non. C’est probablement parce que cela dépend de l’implémentation sous-jacente de la source.

Vous pouvez utiliser le regroupement pour obtenir le résultat souhaité, en obtenant la voiture la plus rapide de chaque fabricant, puis les trois plus rapides:

 var topThreeFastestCarManufacturers = GetAllCars() .GroupBy(c => c.Manufacturer) .Select(g => g.OrderByDescending(c => c.TopSpeed).First()) .OrderByDescending(c => c.TopSpeed) .Take(3); 

Je soupçonne que ce qui va vous gâcher, c’est le Distinct. Cela va probablement réorganiser les résultats par fabricant pour produire des résultats distincts. Il me suffirait probablement de parcourir la liste jusqu’à avoir trois fabricants distincts.

La sélection conserve l’ordre, mais les remarques sur Distinct indiquent qu’elle renvoie un ensemble de résultats non ordonné et qu’elle dépend de la mise en œuvre. Pour être sûr, je ne compterais pas sur le maintien de la commande, mais simplement sur l’itération.

 var top3 = new List(); foreach (var manufacturer in allCarsOrderedFastestToSlowest .Select(car=>car.Manufacturer)) { if (!top3.Contains(manufacturer)) { top3.Add(manufacturer); if (top3.Count == 3) { break; } } }