Ich verwende LINQ to Objects-Anweisungen für ein geordnetes Array. Welche Operationen sollte ich nicht ausführen, um sicherzustellen, dass die Reihenfolge des Arrays nicht geändert wird?
Ich verwende LINQ to Objects-Anweisungen für ein geordnetes Array. Welche Operationen sollte ich nicht ausführen, um sicherzustellen, dass die Reihenfolge des Arrays nicht geändert wird?
Antworten:
Ich habe die Methoden von System.Linq.Enumerable untersucht und alle verworfen , die nicht IEnumerable Ergebnisse lieferten. Ich überprüfte die Bemerkungen der einzelnen, um festzustellen, wie sich die Reihenfolge des Ergebnisses von der Reihenfolge der Quelle unterscheiden würde.
Bewahrt die Ordnung auf jeden Fall. Sie können ein Quellelement nach Index einem Ergebniselement zuordnen
Bewahrt Ordnung. Elemente werden gefiltert oder hinzugefügt, aber nicht neu angeordnet.
Zerstört die Reihenfolge - wir wissen nicht, in welcher Reihenfolge die Ergebnisse zu erwarten sind.
Reihenfolge explizit neu definieren - Verwenden Sie diese, um die Reihenfolge des Ergebnisses zu ändern
Definiert die Reihenfolge nach einigen Regeln neu.
Bearbeiten: Ich habe Distinct basierend auf dieser Implementierung in die Reihenfolge beibehalten verschoben .
private static IEnumerable<TSource> DistinctIterator<TSource>
(IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
{
Set<TSource> set = new Set<TSource>(comparer);
foreach (TSource element in source)
if (set.Add(element)) yield return element;
}
Distinct
Methode) nur "unsortiert" sagen, nicht "in unvorhersehbarer Reihenfolge". Ich würde sagen, Distinct
gehört zur Filterkategorie oben, genau wie Where
.
Sprechen Sie tatsächlich über SQL oder über Arrays? Anders ausgedrückt: Verwenden Sie LINQ to SQL oder LINQ to Objects?
Die Operatoren LINQ to Objects ändern ihre ursprüngliche Datenquelle nicht - sie erstellen Sequenzen, die effektiv von der Datenquelle unterstützt werden. Die einzigen Operationen, die die Reihenfolge ändern, sind OrderBy / OrderByDescending / ThenBy / ThenByDescending - und selbst dann sind diese für gleich geordnete Elemente stabil. Natürlich werden bei vielen Operationen einige Elemente herausgefiltert, aber die zurückgegebenen Elemente befinden sich in derselben Reihenfolge.
Wenn Sie in eine andere Datenstruktur konvertieren, z. B. mit ToLookup oder ToDictionary, glaube ich nicht, dass die Reihenfolge zu diesem Zeitpunkt erhalten bleibt - aber das ist trotzdem etwas anders. (Ich glaube jedoch, dass die Reihenfolge der Werte, die demselben Schlüssel zugeordnet sind, für Suchvorgänge beibehalten wird.)
GroupBy
gefolgt von SelectMany
werden die Ergebnisse nach Schlüssel gruppiert angezeigt, jedoch nicht in aufsteigender Schlüsselreihenfolge. Es werden sie in der Reihenfolge angezeigt, in der die Schlüssel ursprünglich aufgetreten sind.
list<x> {a b c d e f g}
wenn c, d, e alle den gleichen Schlüssel haben, enthält die resultierende Sequenz c, d, e nebeneinander UND in der Reihenfolge c, d, e. Ich kann anscheinend keine kategorische MS-basierte Antwort finden.
Wenn Sie an einem Array arbeiten, klingt es so, als würden Sie LINQ-to-Objects verwenden, nicht SQL. Kannst du bestätigen? Die meisten LINQ-Operationen ordnen nichts neu an (die Ausgabe erfolgt in derselben Reihenfolge wie die Eingabe). Wenden Sie daher keine andere Sortierung an (OrderBy [Absteigend] / ThenBy [Absteigend]).
[Bearbeiten: wie Jon klarer formulierte; LINQ erstellt im Allgemeinen eine neue Sequenz und lässt die Originaldaten in Ruhe.]
Beachten Sie, dass beim Dictionary<,>
Verschieben der Daten in ein (ToDictionary) die Daten verschlüsselt werden, da das Wörterbuch keine bestimmte Sortierreihenfolge berücksichtigt.
Aber die häufigsten Dinge (Auswählen, Wo, Überspringen, Nehmen) sollten in Ordnung sein.
ToDictionary()
macht ich nur keine Zusagen über die Reihenfolge, sondern behalte in der Praxis die Eingabereihenfolge bei (bis Sie etwas daraus entfernen). Ich sage nicht, dass ich mich darauf verlassen soll, aber "Scrambling" scheint ungenau zu sein.
Ich fand eine gute Antwort in einer ähnlichen Frage, die auf offizielle Dokumentation verweist. Um es zu zitieren:
Für Enumerable
Methoden (LINQ to Objects, die gilt List<T>
), können Sie auf die Reihenfolge der Elemente verlassen zurück durch Select
, Where
oder GroupBy
. Dies ist nicht der Fall für Dinge, die von Natur aus ungeordnet sind wie ToDictionary
oder Distinct
.
Von Enumerable.GroupBy Dokumentation:
Die
IGrouping<TKey, TElement>
Objekte werden in einer Reihenfolge ausgegeben, die auf der Reihenfolge der Elemente in der Quelle basiert, die jeweils den ersten Schlüssel erzeugt habenIGrouping<TKey, TElement>
. Elemente in einer Gruppierung werden in der Reihenfolge ausgegeben, in der sie erscheinensource
.
Dies gilt nicht unbedingt für IQueryable
Erweiterungsmethoden (andere LINQ-Anbieter).
Quelle: Behalten die aufzählbaren Methoden von LINQ die relative Reihenfolge der Elemente bei?
Die Frage bezieht sich hier speziell auf LINQ-to-Objects.
Wenn Sie stattdessen LINQ-to-SQL verwenden, gibt es dort keine Reihenfolge, es sei denn, Sie schreiben eine mit etwas wie:
mysqlresult.OrderBy(e=>e.SomeColumn)
Wenn Sie dies mit LINQ-to-SQL nicht tun, kann die Reihenfolge der Ergebnisse zwischen nachfolgenden Abfragen variieren, auch mit denselben Daten, was zu einem zeitweiligen Fehler führen kann.