246 votes

Obtenir une liste de valeurs distinctes dans une liste

En C#, disons que j'ai une classe appelée Note avec trois variables membres de type chaîne.

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

Quelle serait la façon la plus propre d'obtenir une liste de toutes les valeurs distinctes dans la colonne Auteur ?

Je pourrais itérer dans la liste et ajouter toutes les valeurs qui ne sont pas des doublons à une autre liste de chaînes de caractères, mais cela semble sale et inefficace. J'ai l'impression qu'il existe une construction Linq magique qui permet de faire ça en une seule ligne, mais je n'ai rien trouvé.

456voto

Kirk Woll Points 34601
Notes.Select(x => x.Author).Distinct();

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

3 votes

Notes.Select(x => x.Author).AsParallel().Distinct() ; "AsParallel()" peut apporter un avantage en termes de performances, si l'ordre n'est pas important et si la liste comporte plusieurs éléments.

1 votes

@Kiquenet, distinct considérant le Default comparateur d'égalité. msdn.microsoft.com/fr/us/library/bb348436(v=vs.110).aspx

0 votes

Faut-il ajouter ToList() avant .Distinct() ?

128voto

atik sarker Points 198

Distinguer la classe de notes par auteur

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

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

1 votes

Ce n'est pas censé être Notes dans le cas de Notes.GroupBy() avec un pluriel s comme Note ne pourra contenir qu'un seul billet ?

0 votes

@kkuilla merci.

46voto

Dan Busha Points 2373

Jon Skeet a écrit une bibliothèque appelée morelinq qui a un DistinctBy() opérateur. Voir aquí 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 cherchez simplement un ensemble distinct d'Auteurs.

Ajouté un échantillon, plusieurs champs dans DistinctBy :

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

0 votes

Excellent, merci. J'adore le fait qu'il conserve l'ordre correct si j'ordonne la liste avant d'appeler la méthode Distinct.

0 votes

J'ai mis à jour les liens. MoreLINQ est maintenant sur Github et peut être installé via Nuget : Install-Package morelinq

3voto

Bhaskar Points 41
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 l'unique Course s.

-3voto

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

0 votes

Qu'est-ce que mci exactement ? Juste une table d'exemple ? La réponse est un peu difficile à trouver telle quelle.

1 votes

Oui, je ne pense pas que cela réponde à 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 d'auteurs qui pourraient contenir des doublons, mais ne pourrait pas être utilisé pour extraire une telle liste à partir d'une liste d'objets qui ont la chaîne d'auteur comme l'un de leurs champs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X