Ich spiele mit LINQ, um mehr darüber zu erfahren, aber ich kann nicht herausfinden, wie Distinct
ich es verwenden soll, wenn ich keine einfache Liste habe (eine einfache Liste von ganzen Zahlen ist ziemlich einfach, das ist nicht die Frage). Was kann ich tun, wenn Distinct für eine Liste eines Objekts für eine oder mehrere Eigenschaften des Objekts verwendet werden soll?
Beispiel: Wenn ein Objekt ist Person
, mit Eigenschaft Id
. Wie kann ich alle Personen abrufen und Distinct
mit der Eigenschaft Id
des Objekts verwenden?
Person1: Id=1, Name="Test1"
Person2: Id=1, Name="Test1"
Person3: Id=2, Name="Test2"
Wie kann ich nur Person1
und bekommen Person3
? Ist das möglich?
Wenn dies mit LINQ nicht möglich ist, wie lässt sich eine Liste in Person
Abhängigkeit von einigen Eigenschaften in .NET 3.5 am besten erstellen ?
GroupBy
einfacher. Wenn Sie es an mehr als einem Ort benötigen, ist es viel sauberer (IMO), die Absicht zusammenzufassen.IQueryable<T>
, sehe ich nicht, wie relevant es ist. Ich bin damit einverstanden, dass dies nicht für EF usw. geeignet wäre, aber innerhalb von LINQ to Objects denke ich, dass es besser geeignet ist alsGroupBy
. Der Kontext der Frage ist immer wichtig.Einfach! Sie möchten sie gruppieren und einen Gewinner aus der Gruppe auswählen.
Wenn Sie Gruppen für mehrere Eigenschaften definieren möchten, gehen Sie wie folgt vor:
quelle
Single()
undSingleOrDefault()
jeder Wurf, wenn die Quelle mehr als einen Gegenstand hat. Bei dieser Operation erwarten wir die Möglichkeit, dass jede Gruppe mehr als ein Element hat. In diesem FallFirst()
wird es vorgezogen,FirstOrDefault()
weil jede Gruppe mindestens ein Mitglied haben muss ... es sei denn, Sie verwenden EntityFramework, das nicht herausfinden kann, dass jede Gruppe mindestens ein Mitglied hat und Anforderungen stelltFirstOrDefault()
.FirstOrDefault()
github.com/dotnet/efcore/issues/12088 verwende. Ich bin auf 3.1 und bekomme Fehler, dass ich nicht übersetzen kann.Verwenden:
Das
where
hilft Ihnen , die Einträge zu filtern (könnte komplexer sein) und diegroupby
undselect
führen die unterschiedliche Funktion.quelle
Sie können auch die Abfragesyntax verwenden, wenn Sie möchten, dass sie alle LINQ-ähnlich aussieht:
quelle
Ich denke es ist genug:
quelle
Lösung Gruppieren Sie zuerst nach Ihren Feldern und wählen Sie dann das erste oder Standardelement aus.
quelle
Sie können dies mit dem Standard tun
Linq.ToLookup()
. Dadurch wird eine Sammlung von Werten für jeden eindeutigen Schlüssel erstellt. Wählen Sie einfach den ersten Artikel in der Sammlung ausquelle
Der folgende Code entspricht funktional der Antwort von Jon Skeet .
Unter .NET 4.5 getestet, sollte auf jeder früheren Version von LINQ funktionieren.
Schauen Sie sich übrigens Jon Skeets neueste Version von DistinctBy.cs in Google Code an .
quelle
Ich habe einen Artikel geschrieben, in dem erklärt wird, wie die Distinct-Funktion erweitert wird, sodass Sie wie folgt vorgehen können:
Hier ist der Artikel: Erweitern von LINQ - Angeben einer Eigenschaft in der Distinct-Funktion
quelle
Persönlich benutze ich die folgende Klasse:
Dann eine Erweiterungsmethode:
Schließlich die beabsichtigte Verwendung:
Der Vorteil, den ich bei diesem Ansatz gefunden habe, ist die Wiederverwendung von
LambdaEqualityComparer
Klasse für andere Methoden, die eine akzeptierenIEqualityComparer
. (Oh, und ich überlasse dasyield
Zeug der ursprünglichen LINQ-Implementierung ...)quelle
Falls Sie eine Distinct-Methode für mehrere Eigenschaften benötigen, können Sie meine PowerfulExtensions überprüfen Bibliothek . Derzeit befindet es sich in einem sehr jungen Stadium, aber Sie können bereits Methoden wie Distinct, Union, Intersect, außer für eine beliebige Anzahl von Eigenschaften verwenden.
So verwenden Sie es:
quelle
Als wir in unserem Projekt vor einer solchen Aufgabe standen, haben wir eine kleine API definiert, um Komparatoren zu erstellen.
Der Anwendungsfall war also wie folgt:
Und die API selbst sieht folgendermaßen aus:
Weitere Details finden Sie auf unserer Website: IEqualityComparer in LINQ .
quelle
Mit DistinctBy () können Sie Distinct-Datensätze anhand einer Objekteigenschaft abrufen. Fügen Sie einfach die folgende Anweisung hinzu, bevor Sie sie verwenden:
und verwenden Sie es dann wie folgt:
Dabei ist 'Index' die Eigenschaft, für die die Daten unterschiedlich sein sollen.
quelle
Sie können es so machen (wenn auch nicht blitzschnell):
Das heißt: "Wählen Sie alle Personen aus, bei denen die Liste keine andere Person mit derselben ID enthält."
Wohlgemerkt, in Ihrem Beispiel würde das nur Person 3 auswählen. Ich bin mir nicht sicher, wie ich aus den beiden vorherigen sagen soll, was Sie wollen.
quelle
Wenn Sie die MoreLinq-Bibliothek nicht zu Ihrem Projekt hinzufügen möchten, um die
DistinctBy
Funktionalität zu erhalten , können Sie das gleiche Endergebnis erzielen, indem Sie die Überladung der Linq-Distinct
Methode verwenden, die einIEqualityComparer
Argument enthält.Sie erstellen zunächst eine generische benutzerdefinierte Gleichheitsvergleichsklasse, die die Lambda-Syntax verwendet, um einen benutzerdefinierten Vergleich zweier Instanzen einer generischen Klasse durchzuführen:
Dann verwenden Sie es in Ihrem Hauptcode wie folgt:
Voila! :) :)
Das Obige setzt Folgendes voraus:
Person.Id
ist vom Typint
people
Sammlung enthält keine NullelementeWenn die Sammlung Nullen enthalten könnte, schreiben Sie die Lambdas einfach neu, um nach Null zu suchen, z.
BEARBEITEN
Dieser Ansatz ähnelt dem in der Antwort von Vladimir Nesterovsky, ist jedoch einfacher.
Es ähnelt auch dem in Joels Antwort, ermöglicht jedoch eine komplexe Vergleichslogik mit mehreren Eigenschaften.
Wenn sich Ihre Objekte jedoch nur bis dahin unterscheiden können,
Id
hat ein anderer Benutzer die richtige Antwort gegeben. Sie müssen lediglich die Standardimplementierungen vonGetHashCode()
undEquals()
in IhrerPerson
Klasse überschreiben und dann einfach die Out-of-the-Box-Distinct()
Methode von Linq zum Filtern verwenden Duplikate aus.quelle
Der beste Weg, dies zu tun, der mit anderen .NET-Versionen kompatibel ist, besteht darin, Equals und GetHash zu überschreiben, um dies zu handhaben (siehe Frage zum Stapelüberlauf. Dieser Code gibt unterschiedliche Werte zurück. Ich möchte jedoch eine stark typisierte Sammlung im Gegensatz zu zurückgeben ein anonymer Typ ), aber wenn Sie etwas benötigen, das im gesamten Code allgemein gehalten ist, sind die Lösungen in diesem Artikel großartig.
quelle
quelle
Select()
new Person
stattnew Player
? Die Tatsache, dass Sie bei bestellen,ID
informiert Sie jedoch nicht darüberDistinct()
, diese Eigenschaft zur Bestimmung der Eindeutigkeit zu verwenden, sodass dies nicht funktioniert.Überschreibung equals (Objekt obj) und GetHashCode () Methode:
und dann einfach anrufen:
quelle
Sie sollten in der Lage sein, Equals on person zu überschreiben, um Equals on Person.id tatsächlich auszuführen. Dies sollte zu dem Verhalten führen, nach dem Sie suchen.
quelle
Bitte versuchen Sie es mit dem folgenden Code.
quelle