Rufen Sie eine Liste mit unterschiedlichen Werten in der Liste ab


175

Angenommen, ich habe in C # eine Klasse namens Note mit drei String-Mitgliedsvariablen.

public class Note
{
    public string Title;
    public string Author;
    public string Text;
}

Und ich habe eine Liste vom Typ Hinweis:

List<Note> Notes = new List<Note>();

Was wäre der sauberste Weg, um eine Liste aller unterschiedlichen Werte in der Spalte Autor zu erhalten?

Ich könnte die Liste durchlaufen und alle Werte, die keine Duplikate sind, zu einer anderen Liste von Zeichenfolgen hinzufügen, aber dies scheint schmutzig und ineffizient zu sein. Ich habe das Gefühl, dass es eine magische Linq-Konstruktion gibt, die dies in einer Zeile erledigt, aber ich konnte mir nichts einfallen lassen.

Antworten:


331
Notes.Select(x => x.Author).Distinct();

Dies gibt eine Folge ( IEnumerable<string>) von AuthorWerten zurück - einen pro eindeutigem Wert.


1
Notes.Select (x => x.Author) .AsParallel (). Distinct (); "AsParallel ()" kann einen Leistungsvorteil bieten, wenn wir uns nicht um die Reihenfolge kümmern und mehr Artikel in der Liste haben.
Sai

1
@Kiquenet, unter Berücksichtigung des DefaultGleichheitsvergleichs unterschiedlich. msdn.microsoft.com/en-us/library/bb348436(v=vs.110).aspx
Georg Patscheider

Müssen wir ToList () vor .Distinct () hinzufügen?
Phan Đức Bình

1
Nicht vor dem Distinct (), sondern danach, wenn Sie versuchen, in eine Liste zu konvertieren. Beispiel: Notes.Select (x => x.Author) .Distinct (). ToList ();
MTwiford

87

Unterscheiden Sie die Note-Klasse nach Autor

var DistinctItems = Note.GroupBy(x => x.Author).Select(y => y.First());

foreach(var item in DistinctItems)
{
    //Add to other List
}

1
Soll es nicht Notesso in Notes.GroupBy()einem Plural sein, swie Notees nur eine einzige Note enthält?
Kkuilla

30

Jon Skeet hat eine Bibliothek namens morelinq geschrieben, die einen DistinctBy()Operator hat. Siehe hier für die Implementierung. Ihr Code würde so aussehen

IEnumerable<Note> distinctNotes = Notes.DistinctBy(note => note.Author);

Update: Nach dem erneuten Lesen Ihrer Frage hat Kirk die richtige Antwort, wenn Sie nur nach einer bestimmten Gruppe von Autoren suchen.

Beispiel hinzugefügt, mehrere Felder in DistinctBy:

res = res.DistinctBy(i => i.Name).DistinctBy(i => i.ProductId).ToList();

Ausgezeichnet, vielen Dank. Ich finde es toll, dass es die richtige Reihenfolge beibehält, wenn ich die Liste bestelle, bevor ich die Distinct-Methode aufrufe.
Vilhelm

Ich habe die Links aktualisiert. MoreLINQ ist jetzt auf Github und kann über Nuget installiert werden:Install-Package morelinq
Chad Levy

2
public class KeyNote
{
    public long KeyNoteId { get; set; }
    public long CourseId { get; set; }
    public string CourseName { get; set; }
    public string Note { get; set; }
    public DateTime CreatedDate { get; set; }
}

public List<KeyNote> KeyNotes { get; set; }
public List<RefCourse> GetCourses { get; set; }    

List<RefCourse> courses = KeyNotes.Select(x => new RefCourse { CourseId = x.CourseId, Name = x.CourseName }).Distinct().ToList();

Mit der obigen Logik können wir die eindeutigen Courses erhalten.


Ihr Distinct vor ToList spart mir Zeit. Ich mache nach ToList und gebe den Fehler aus, dass die Liste nicht in Ienumerable konvertiert werden kann.
Ajay2707

Distinct funktioniert hier nicht, da für diesen Operator jedes Objekt basierend auf dem Hashcode des Objekts eindeutig ist. Sie benötigen ähnliche - github.com/morelinq/MoreLINQ/blob/master/MoreLinq/DistinctBy.cs
Bose_geek

-2
mcilist = (from mci in mcilist select mci).Distinct().ToList();

Was genau ist mci? Nur eine Beispieltabelle? Die Antwort ist etwas umständlich.
Brad Koch

1
Ja, ich glaube nicht, dass dies das tut, wonach meine ursprüngliche Frage gesucht hat (egal, es war vor anderthalb Jahren und das Projekt ist längst abgeschlossen). Soweit ich das beurteilen kann, würde dies funktionieren, wenn ich bereits eine Liste von Autorenzeichenfolgen hätte, die möglicherweise Duplikate enthalten, aber nicht verwendet werden könnten, um eine solche Liste aus einer Liste von Objekten zu extrahieren, deren Autorenzeichenfolge die Autorenzeichenfolge ist.
Darrel Hoffman
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.