292 votes

Sélectionnez distinct en utilisant Linq

J'ai une liste de classes de classe

public class LinqTest
{
public int id { get; set; }
public string value { get; set; }
}

List myList = new List();
myList.Add(new LinqTest() { id = 1, value = "a" });
myList.Add(new LinqTest() { id = 1, value = "b" });
myList.Add(new LinqTest() { id = 2, value = "c" });

Je dois sélectionner uniquement les id distincts de cette liste. c'est-à-dire, ma liste résultante ne doit contenir que

[{id=1,value="a"},{ id = 2, value = "c" }]

Comment puis-je faire cela avec Linq?

Modifier

Entrée,

id      value
1        a
1        b
2        c
3        d
3        e

La sortie devrait être,

id      value
1        a
2        c
3        d

c'est-à-dire, s'il y a une répétition de id, le résultat devrait prendre seulement la première occurrence.

592voto

Paul Ruane Points 12840
myList.GroupBy(test => test.id)
      .Select(grp => grp.First());

Edit : comme obtenir ce IEnumerable<> dans une List<> semble être un mystère pour beaucoup de gens, vous pouvez simplement écrire :

var result = myList.GroupBy(test => test.id)
                   .Select(grp => grp.First())
                   .ToList();

Mais il est souvent préférable de travailler avec l'IEnumerable plutôt qu'avec IList car la Linq ci-dessus est évaluée de manière paresseuse : elle ne réalise réellement tout le travail que lorsque l'énumérable est itéré. Lorsque vous appelez ToList, elle parcourt réellement l'ensemble de l'énumérable, forçant ainsi la réalisation de tout le travail immédiatement. (Et cela peut prendre un peu de temps si votre énumérable est infiniment long.)

Le revers de ce conseil est que chaque fois que vous énumérez un tel IEnumerable, le travail pour l'évaluer doit être refait à neuf. Vous devez donc décider pour chaque cas s'il est préférable de travailler avec l'IEnumerable évaluée de manière paresseuse ou de la réaliser dans une List, un Set, un Dictionary ou autre chose.

142voto

Daniel Hilgarth Points 90722

En utilisant morelinq vous pouvez utiliser DistinctBy:

myList.DistinctBy(x => x.id);

Autrement, vous pouvez utiliser un groupe:

myList.GroupBy(x => x.id)
      .Select(g => g.First());

63voto

Tim Schmelter Points 163781

Vous devriez remplacer Equals et GetHashCode de manière significative, dans ce cas pour comparer l'ID :

public class LinqTest
{
    public int id { get; set; }
    public string value { get; set; }

    public override bool Equals(object obj)
    {
        LinqTest obj2 = obj as LinqTest;
        if (obj2 == null) return false;
        return id == obj2.id;
    }

    public override int GetHashCode()
    {
        return id;
    }
}

Maintenant vous pouvez utiliser Distinct:

List uniqueIDs = myList.Distinct().ToList();

30voto

Tim Rogers Points 9956
myList.GroupBy(i => i.id).Select(group => group.First())

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