Quelqu'un a-t-il une méthode rapide pour dédupliquer une liste générique en C #?
c#
list
generics
duplicates
JC Grubbs
la source
la source
ICollection<MyClass> withoutDuplicates = new HashSet<MyClass>(inputList);
Réponses:
Vous devriez peut-être envisager d'utiliser un HashSet .
À partir du lien MSDN:
la source
HashSet
n'a pas d'index , il n'est donc pas toujours possible de l'utiliser. Je dois créer une fois une énorme liste sans doublons, puis l'utiliser pourListView
le mode virtuel. Il était super rapide de faire uneHashSet<>
première, puis de la convertir en unList<>
(doncListView
on peut accéder aux éléments par index).List<>.Contains()
est trop lent.Si vous utilisez .Net 3+, vous pouvez utiliser Linq.
la source
Que diriez-vous:
Dans .net 3.5?
la source
Initialisez simplement un HashSet avec une liste du même type:
Ou, si vous souhaitez renvoyer une liste:
la source
List<T>
utilisation en conséquencenew HashSet<T>(withDupes).ToList()
Triez-le, puis cochez deux et deux côte à côte, car les doublons s'agglutineront.
Quelque chose comme ça:
Remarques:
la source
RemoveAt
est une opération très coûteuse sur unList
J'aime utiliser cette commande:
J'ai ces champs dans ma liste: Id, StoreName, City, PostalCode Je voulais afficher la liste des villes dans une liste déroulante qui a des valeurs en double. solution: Groupez par ville puis choisissez le premier pour la liste.
J'espère que ça aide :)
la source
Ça a marché pour moi. utilisez simplement
Remplacez "Type" par le type souhaité, par exemple int.
la source
Comme l'a dit kronoz dans .Net 3.5, vous pouvez utiliser
Distinct()
.Dans .Net 2, vous pouvez l'imiter:
Cela pourrait être utilisé pour dédupliquer n'importe quelle collection et retournera les valeurs dans l'ordre d'origine.
Il est normalement beaucoup plus rapide de filtrer une collection (comme le font les deux
Distinct()
et cet exemple) que de supprimer des éléments de celle-ci.la source
HashSet
constructeur avait détruit, ce qui le rend meilleur dans la plupart des cas. Cependant, cela conserverait l'ordre de tri, ce quiHashSet
n'est pas le cas.Dictionary<T, object>
place, remplacer.Contains
par.ContainsKey
et.Add(item)
avec.Add(item, null)
HashSet
préserve l'ordre alorsDistinct()
que non.Une méthode d'extension pourrait être une bonne façon de procéder ... quelque chose comme ceci:
Et puis appelez comme ceci, par exemple:
la source
En Java (je suppose que C # est plus ou moins identique):
Si vous vouliez vraiment muter la liste originale:
Pour préserver l'ordre, remplacez simplement HashSet par LinkedHashSet.
la source
var noDupes = new HashSet<T>(list); list.Clear(); list.AddRange(noDupes);
:)Cela prend des éléments distincts (les éléments sans éléments en double) et les convertit à nouveau en liste:
la source
Remarque: Cette solution ne nécessite aucune connaissance de Linq, à part qu'elle existe.
Code
Commencez par ajouter ce qui suit en haut de votre fichier de classe:
Maintenant, vous pouvez utiliser ce qui suit pour supprimer les doublons d'un objet appelé
obj1
:Remarque: Renommez
obj1
le nom de votre objet.Comment ça fonctionne
La commande Union répertorie une entrée de chaque entrée de deux objets source. Étant donné que obj1 est les deux objets source, cela réduit obj1 à l'une de chaque entrée.
La
ToList()
renvoie une nouvelle liste. Cela est nécessaire, car les commandes Linq commeUnion
renvoie le résultat en tant que résultat IEnumerable au lieu de modifier la liste d'origine ou de renvoyer une nouvelle liste.la source
Comme méthode d'assistance (sans Linq):
la source
Si vous ne se soucient pas de l'ordre que vous pouvez juste pousser les éléments dans un
HashSet
, si vous ne voulez maintenir l'ordre que vous pouvez faire quelque chose comme ceci:Ou à la manière Linq:
Edit: La
HashSet
méthode est leO(N)
temps et l'O(N)
espace tout en triant puis en rendant unique (comme suggéré par @ lassevk et d'autres) est leO(N*lgN)
temps et l'O(1)
espace donc il n'est pas si clair pour moi (comme c'était à première vue) que le mode de tri est inférieur (mon excuses pour le vote temporaire de baisse ...)la source
Voici une méthode d'extension pour supprimer les doublons adjacents in situ. Appelez d'abord Sort () et passez le même IComparer. Cela devrait être plus efficace que la version de Lasse V. Karlsen qui appelle RemoveAt à plusieurs reprises (entraînant plusieurs mouvements de mémoire de bloc).
la source
En installant le package MoreLINQ via Nuget, vous pouvez facilement distinguer la liste d'objets par une propriété
la source
Il pourrait être plus facile de simplement s'assurer que les doublons ne sont pas ajoutés à la liste.
la source
List<T>.Contains
méthode à chaque fois mais avec plus de 1 000 000 d'entrées. Ce processus ralentit ma candidature. J'utilise uneList<T>.Distinct().ToList<T>()
première à la place.Vous pouvez utiliser Union
la source
Une autre façon dans .Net 2.0
la source
Il existe de nombreuses façons de résoudre le problème des doublons dans la liste ci-dessous:
Bravo Ravi Ganesan
la source
Voici une solution simple qui ne nécessite aucun LINQ difficile à lire ni aucun tri préalable de la liste.
la source
La réponse de David J. est une bonne méthode, pas besoin d'objets supplémentaires, de tri, etc. Elle peut cependant être améliorée:
for (int innerIndex = items.Count - 1; innerIndex > outerIndex ; innerIndex--)
Ainsi, la boucle externe va en haut en bas pour toute la liste, mais la boucle interne va en bas "jusqu'à ce que la position de la boucle externe soit atteinte".
La boucle externe s'assure que toute la liste est traitée, la boucle interne trouve les doublons réels, ceux-ci ne peuvent se produire que dans la partie que la boucle externe n'a pas encore traitée.
Ou si vous ne voulez pas faire de bas en haut pour la boucle intérieure, vous pouvez faire démarrer la boucle intérieure à externalIndex + 1.
la source
Toutes les réponses copient des listes, ou créent une nouvelle liste, ou utilisent des fonctions lentes, ou sont tout simplement douloureusement lentes.
À ma connaissance, c'est la méthode la plus rapide et la moins chère que je connaisse (également, soutenue par un programmeur très expérimenté spécialisé dans l'optimisation physique en temps réel).
Le coût final est:
nlogn + n + nlogn = n + 2nlogn = O (nlogn) ce qui est plutôt sympa.
Remarque sur RemoveRange: Étant donné que nous ne pouvons pas définir le nombre de la liste et éviter d'utiliser les fonctions Remove, je ne connais pas exactement la vitesse de cette opération, mais je suppose que c'est le moyen le plus rapide.
la source
Si vous avez des classes de remorquage
Product
etCustomer
que nous voulons supprimer les éléments en double de leur listeVous devez définir une classe générique dans le formulaire ci-dessous
vous pouvez ensuite supprimer les éléments en double de votre liste.
supprimer ce code doublons par
Id
si vous voulez supprimer les doublons par d' autres biens, vous pouvez modifiernameof(YourClass.DuplicateProperty)
mêmenameof(Customer.CustomerName)
supprimer les doublons puis par laCustomerName
propriété.la source
la source
Une implémentation simple et intuitive:
la source