Ich suche nach einer Möglichkeit, die Wiederholung von Elementen in einer Liste zu verhindern, aber die Reihenfolge beizubehalten. Zum Beispiel
%Vor%sollte
werden %Vor% Ich habe es ziemlich unelegant mit einer for
Schleife gemacht, indem ich das nächste Element wie folgt überprüft habe
Gibt es einen eleganteren Weg dies zu tun, vorzugsweise mit LINQ?
Sie können eine Erweiterungsmethode erstellen:
%Vor%Verwendung:
%Vor%Du könntest einfach LINQ schreiben:
%Vor%oder Pythonic (gut, mein bester Versuch) Weg:
%Vor%Der einfachste ( bearbeiten: hat nicht gesehen, dass es bereits von King King )
%Vor%Wenn Sie eine LINQ-Anweisung wünschen, die nicht auf den erfassten Wert des Ergebnisses innerhalb des Aufrufs angewiesen ist, benötigen Sie ein Konstrukt mit Aggregat, da es die einzige Methode ist, die zusammen mit der Operation einen Wert liefert. I.e. basierend auf Zaheer Ahmeds Code:
%Vor% Oder Sie können sogar versuchen, eine Liste ohne if
:
Hinweis: Um eine angemessene Leistung der obigen Beispiele mit Aggregate
zu erhalten, müssten Sie auch den letzten Wert tragen ( Last
muss die gesamte Sequenz in jedem Schritt durchlaufen), aber Code, der 3 Werte {IsEmpty, LastValue, Sequence}
in a enthält Tuple
ist sehr seltsam aussehend. Diese Beispiele dienen nur Unterhaltungszwecken.
Eine weitere Option ist, dass Zip
array mit sich selbst um 1 verschoben wird und Elemente zurückgibt, die nicht gleich sind ...
Eine praktikablere Option besteht darin, einen Iterator zu erstellen, der Werte filtert:
%Vor%Wenn du wirklich die Welt hasst, pure LINQ:
%Vor% Beachten Sie jedoch, dass Sie (mindestens teilweise) das Aufzählungszeichen 3 (der Take
, der "linke" Teil von Zip
, die ersten Parameter von Zip
) aufzählen müssen. Diese Methode ist langsamer als das Erstellen einer yield
-Methode oder das direkte Ausführen .
Erläuterung:
.Take(1)
) .Skip(1)
) und paaren sie mit allen Zahlen ( .Zip(nmbs
). Wir nennen curr
die Zahlen aus der ersten "Sammlung" und prev
die Zahlen aus der zweiten "Sammlung" ( (p, q) => new { prev = q, curr = p })
). Sie nehmen dann nur die Zahlen, die sich von der vorherigen Zahl unterscheiden ( .Where(p => p.prev != p.curr)
) und von diesen nehmen Sie den curr
-Wert und verwerfen den prev
-Wert ( .Select(p => p.curr)
) .Concat(
) Hier der Code, den Sie brauchen:
%Vor%Die LINQ Magie ist:
%Vor%Oder Sie können eine Erweiterungsmethode wie folgt erstellen:
%Vor%Überprüfen Sie, ob der letzte der neuen Liste und der aktuelle Eintrag nicht gleich sind, und fügen Sie ihn zu der neuen Liste hinzu:
%Vor%oder LINQ:
%Vor%Habe eine korrekte Validierung für das Null-Objekt.