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.

Réponses:


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

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


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
}

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

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 .


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

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.