wake-up-neo.com

Wie kann man eine Liste von einer Liste von Objekten unterscheiden?

Ich habe einen List<MyClass> someList.

class MyClass
{
    public int Prop1...
    public int Prop2...
    public int Prop3...
}

Ich möchte wissen, wie ich einen neuen eindeutigen List<MyClass> distinctList von List<MyClass> someList erhalten kann, aber ich möchte ihn nur mit Prop2 vergleichen.

37
Willem

Leider gibt es im Framework keine wirklich einfache Unterstützung dafür - aber Sie können die DistinctBy -Implementierung verwenden, die ich in MoreLINQ habe.

Sie würden verwenden:

var distinctList = someList.DistinctBy(x => x.Prop2).ToList();

(Sie können nur die DistinctBy-Implementierung verwenden. Wenn Sie lieber eine Microsoft-Implementierung verwenden, glaube ich, dass in der System.Interactive-Assembly von Reactive Extensions etwas ähnliches vorhanden ist.)

41
Jon Skeet

Sie können den Effekt von DistinctBy mit GroupBy emulieren und dann nur den ersten Eintrag in jeder Gruppe verwenden. Könnte etwas langsamer sein als die anderen Implementierungen.

someList.GroupBy(elem=>elem.Prop2).Select(group=>group.First());
79
CodesInChaos

sie müssen die Erweiterungsmethode .Distinct(..); ..__ verwenden. Hier ein kurzes Beispiel:

public class Comparer : IEqualityComparer<Point>
    {
        public bool Equals(Point x, Point y)
        {
            return x.X == y.X;
        }

        public int GetHashCode(Point obj)
        {
            return (int)obj.X;
        }
    }

Vergessen Sie nicht GetHashCode.

Verwendungszweck:

List<Point> p = new List<Point>();
// add items
p.Distinct(new Comparer());
19
Ilya Smagin

Überschreiben Sie Gleiche (Objekt obj) und GetHashCode () Methoden:

class MyClass
{
    public int Prop1 { get; set; }
    public int Prop2 { get; set; }
    public int Prop3 { get; set; }

    public override bool Equals(object obj)
    {
        return ((MyClass)obj).Prop2 == Prop2;
    }
    public override int GetHashCode()
    {
        return Prop2.GetHashCode();
    }
}

und dann einfach anrufen:

List<MyClass> distinctList = someList.Distinct().ToList();

Erstellen Sie eine Klasse, die die Schnittstelle IEqualityComparer implementiert, die nur nach Ihrer Prop2-Eigenschaft sucht. Sie können dann eine Instanz dieser Klasse an die Erweiterungsmethode Distinct übergeben.

2
Christian

Sieben. Jahre. Später.

Ich weiß, dass es eine Weile her ist, aber ich brauchte die einfachste Antwort, und zu diesem Zeitpunkt (mit .NET 4.5.1) fand ich Folgendes als die einfachste Antwort, die ich bekommen konnte:

IEnumerable<long> allIds = waitingFiles.Values.Select(wf => wf.groupId).Distinct();

Meine Situation ist, dass ich ein ConcurrentDictionary habe, das ungefähr so ​​aussieht: ConcurrentDictionary<long, FileModel>

Die ConcurrentDictionary Values-Eigenschaft ist im Grunde mein List<FileModel>.

* FileModel hat eine groupId, die nicht unbedingt eindeutig ist (obwohl natürlich der Schlüssel (long), den ich zum Hinzufügen des FileModel-Objekts in das Wörterbuch verwende, für FileModel eindeutig ist).

* Aus Gründen der Übersichtlichkeit im Beispiel genannt.

Der Punkt ist, dass ich eine große Anzahl von FileModels (von 100) im ConcurrentDictionary habe, und in diesen 100 FileModels gibt es 5 verschiedene groupIds.

An dieser Stelle brauche ich nur eine Liste der verschiedenen groupId.

Wenn ich also nur eine Liste von FileModel hätte, würde der Code folgendermaßen aussehen:

IEnumerable <long> allIds = allFileModel.Select(fm => fm.groupId).Distinct();
1
raddevus

Verwenden Sie einfach die eingebaute Funktion DistinctBy der Bibliothek des Microsoft Ajax-Dienstprogramms wie das Beispiel:

Zuerst inklusive Bibliothek

using Microsoft.Ajax.Utilities;

dann

var distinctList = yourList.DistinctBy(x => x.Prop2).ToList();
0
Anh Hoang