Obtenir une liste de valeurs distinctes dans List

175

En C #, disons que j'ai une classe appelée Note avec trois variables membres String.

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

Et j'ai une liste de type Note:

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

Quel serait le moyen le plus propre d'obtenir une liste de toutes les valeurs distinctes dans la colonne Auteur?

Je pourrais parcourir la liste et ajouter toutes les valeurs qui ne sont pas des doublons à une autre liste de chaînes, mais cela semble sale et inefficace. J'ai le sentiment qu'il y a une construction Linq magique qui fera cela en une seule ligne, mais je n'ai rien pu trouver.

Darrel Hoffman
la source

Réponses:

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

Cela renverra une séquence ( IEnumerable<string>) de Authorvaleurs - une par valeur unique.

Kirk Woll
la source
1
Notes.Select (x => x.Auteur) .AsParallel (). Distinct (); "AsParallel ()" peut donner un certain avantage en termes de performances, si nous ne nous soucions pas de l'ordre et que nous avons plus d'éléments dans la liste.
Sai
1
@Kiquenet, distinct compte tenu du Defaultcomparateur d'égalité. msdn.microsoft.com/en-us/library/bb348436(v=vs.110).aspx
Georg Patscheider
Doit-on ajouter ToList () avant .Distinct ()?
Phan Đức Bình
1
Pas avant le Distinct () mais après, si vous essayez de convertir en liste. Ex: Notes.Select (x => x.Author) .Distinct (). ToList ();
MTwiford
87

Distinction de la classe Note par auteur

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

foreach(var item in DistinctItems)
{
    //Add to other List
}
atik sarker
la source
1
Est - il pas censé être Notescomme Notes.GroupBy()un pluriel scomme Notedétiendra uniquement un seul billet?
kkuilla
30

Jon Skeet a écrit une bibliothèque appelée morelinq qui a un DistinctBy()opérateur. Voir ici pour l'implémentation. Votre code ressemblerait à

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

Mise à jour: après avoir relu votre question, Kirk a la bonne réponse si vous recherchez simplement un ensemble distinct d'auteurs.

Exemple ajouté, plusieurs champs dans DistinctBy:

res = res.DistinctBy(i => i.Name).DistinctBy(i => i.ProductId).ToList();
Dan Busha
la source
Excellent merci. J'adore le fait qu'il garde le bon ordre si je commande la liste avant d'appeler la méthode Distinct.
Vilhelm
J'ai mis à jour les liens. MoreLINQ est maintenant sur Github et peut être installé via Nuget: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();

En utilisant la logique ci-dessus, nous pouvons obtenir les Courses uniques .

Bhaskar
la source
votre Distinct avant ToList économiser mon temps .. Je fais après ToList et donne l'erreur qui ne peut pas convertir la liste en Ienumerable.
Ajay2707 le
Distinct ne fonctionnera pas ici car pour cet opérateur, chaque objet est unique en fonction du hashcode de l'objet. Vous avez besoin de quelque chose de similaire - github.com/morelinq/MoreLINQ/blob/master/MoreLinq/DistinctBy.cs
Bose_geek
-2
mcilist = (from mci in mcilist select mci).Distinct().ToList();
ravinderreddy Seeelam
la source
Qu'est-ce que mci exactement? Juste un exemple de tableau? La réponse est un peu maladroite en l'état.
Brad Koch
1
Oui, je ne pense pas que cela fasse ce que ma question initiale recherchait (peu importe, c'était il y a un an et demi et le projet est terminé depuis longtemps). D'après ce que je peux dire, cela fonctionnerait si j'avais déjà une liste de chaînes Auteur qui pourraient contenir des doublons, mais ne pourrait pas être utilisée pour extraire une telle liste d'une liste d'objets qui ont la chaîne Auteur comme l'un de leurs champs.
Darrel Hoffman