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.
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.)
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());
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());
Ü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.
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();
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();