391 votes

Supprimer les doublons dans la liste en utilisant linq

J'ai une classe Items avec properties (Id, Name, Code, Price) .

La liste des Items est rempli d'éléments dupliqués.

Par exemple.. :

1         Item1       IT00001        $100
2         Item2       IT00002        $200
3         Item3       IT00003        $150
1         Item1       IT00001        $100
3         Item3       IT00003        $150

Comment supprimer les doublons dans la liste en utilisant linq ?

0 votes

J'ai aussi une autre classe comme propriété dans la classe des éléments.

0 votes

Vous pouvez également faire var set = new HashSet<int>(); var uniques = items.Where(x => set.Add(x.Id)); . Il devrait être criminel de le faire

754voto

Freddy Points 2081
var distinctItems = items.GroupBy(x => x.Id).Select(y => y.First());

41 votes

Merci - je cherchais à éviter d'écrire une classe de comparaison donc je suis content que cela fonctionne :)

12 votes

+1 Cette solution permet même de départager les ex-aequo : éliminer les doublons avec des critères !

6 votes

Mais un peu plus haut !

464voto

Christian Hayter Points 17999
var distinctItems = items.Distinct();

Pour ne faire correspondre que certaines des propriétés, créez un comparateur d'égalité personnalisé, par exemple :

class DistinctItemComparer : IEqualityComparer<Item> {

    public bool Equals(Item x, Item y) {
        return x.Id == y.Id &&
            x.Name == y.Name &&
            x.Code == y.Code &&
            x.Price == y.Price;
    }

    public int GetHashCode(Item obj) {
        return obj.Id.GetHashCode() ^
            obj.Name.GetHashCode() ^
            obj.Code.GetHashCode() ^
            obj.Price.GetHashCode();
    }
}

Alors utilisez-le comme ceci :

var distinctItems = items.Distinct(new DistinctItemComparer());

0 votes

Bonjour Christian, Quel sera le changement dans le code si j'ai une liste<my_Custom_Class> et une liste<string>. Ma classe personnalisée a plusieurs éléments dont l'un est le numéro DCN et la liste<string> a seulement le numéro DCN. J'ai donc besoin de vérifier si la liste<Custom_Class> contient un DCN de la liste<string>. Par exemple, supposons que List1 = List<Custom_Class> et List2 = List<String>. Si List1 a 2000 éléments et List2 a 40000 éléments sur lesquels 600 éléments de List1 existent dans List2. Donc dans ce cas, j'ai besoin de 1400 comme liste de sortie en tant que liste 1. Alors quelle serait l'expression. Merci d'avance

0 votes

Il y a aussi un autre cas, puisque la liste 1 contient plusieurs éléments, les valeurs des autres éléments peuvent être différentes mais le DCN doit être le même. Donc dans mon cas, Distinct n'a pas réussi à donner le résultat souhaité.

3 votes

Je trouve les cours de comparateurs extrêmement utiles. Elles peuvent exprimer une logique autre que de simples comparaisons de noms de propriétés. J'en ai écrit une nouvelle le mois dernier, pour faire quelque chose que GroupBy ne pouvait pas.

48voto

tvanfosson Points 268301

S'il y a quelque chose qui perturbe votre requête Distinct, vous devriez peut-être regarder dans PlusLinq et utiliser l'opérateur DistinctBy pour sélectionner les objets distincts par leur identifiant.

var distinct = items.DistinctBy( i => i.Id );

1 votes

Il n'existe pas de méthode DistinctBy() avec Linq.

14 votes

@FereydoonBarikzehy Mais il ne parle pas de Linq pur. Dans le post, il s'agit de linq pour le projet MoreLinq ...

34voto

Victor Juri Points 423

C'est ainsi que j'ai pu regrouper par avec Linq. J'espère que cela vous aidera.

var query = collection.GroupBy(x => x.title).Select(y => y.FirstOrDefault());

3 votes

@nawfal, je suggérais FirstOrDefault() au lieu de First().

36 votes

Si je ne me trompe pas, en utilisant FirstOrDefault ici n'offre aucun avantage si le Select immédiatement après GroupBy puisqu'il n'est pas possible qu'il y ait un groupe vide (les groupes étaient juste dérivé du contenu de la collection)

17voto

Brian Rasmussen Points 68853

Utilice Distinct() mais gardez à l'esprit qu'il utilise le comparateur d'égalité par défaut pour comparer les valeurs, donc si vous voulez quelque chose de plus que cela, vous devez implémenter votre propre comparateur.

Veuillez consulter http://msdn.microsoft.com/en-us/library/bb348436.aspx pour un exemple.

0 votes

Je dois noter que le comparateur par défaut fonctionne si les types de membres de la collection sont des types de valeurs. Mais quel est le comparateur d'égalité par défaut sélectionné par le csc pour les types de référence. Les types de référence doivent avoir leur propre(s) comparateur(s).

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