Vérification d'une liste avec des valeurs null pour les doublons en C#

En C#, je peux utiliser quelque chose comme:

List<string> myList = new List<string>();

if (myList.Count != myList.Distinct().Count())
{
    // there are duplicates
}

Pour vérifier les éléments en double dans une liste. Cependant, lorsqu'il y a des éléments null dans la liste, cela produit un faux positif. Je peux le faire en utilisant un code lent, mais existe-t-il un moyen de vérifier les doublons dans une liste tout en ignorant les valeurs nulles d'une manière concise ?

32
demandé sur Cemre 2013-06-06 15:04:03

5 réponses

Je le ferais différemment:

Étant donné que les instructions Linq seront évaluées paresseusement, le {[1] } court-circuitera-ce qui signifie que vous n'avez pas à itérer et compter toute la liste, s'il y a des doublons - et en tant que tel, devrait être plus efficace.

var dupes = myList
    .Where(item => item != null)
    .GroupBy(item => item)
    .Any(g => g.Count() > 1);

if(dupes)
{
    //there are duplicates
}

Modifier: http://pastebin.com/b9reVaJu un benchmarking Linqpad que semble conclure GroupBy avec Count() est plus rapide

EDIT 2: la réponse de Rawling ci-dessous semble au moins 5 fois plus rapide que cela l'approche!

32
répondu Dave Bish 2013-06-06 13:36:11

Si vous êtes inquiet pour les performances, le code suivant s'arrêtera dès qu'il trouvera le premier élément dupliqué - toutes les autres solutions jusqu'à présent nécessitent que l'entrée entière soit itérée au moins une fois.

var hashset = new HashSet<string>();
if (myList.Where(s => s != null).Any(s => !hashset.Add(s)))
{
    // there are duplicates
}

hashset.Add renvoie false si l'élément existe déjà dans l'ensemble, et Any renvoie true dès que la première valeur true se produit, donc cela ne recherchera l'entrée que jusqu'au premier doublon.

56
répondu Rawling 2013-06-06 11:43:40
var nonNulls = myList.Where(x => x != null)
if (nonNulls.Count() != nonNulls.Distinct().Count())
{
    // there are duplicates
}
11
répondu Joe 2013-06-06 11:06:13

Eh bien, deux NULL sont des doublons, n'est-ce pas?

Quoi qu'il en soit, comparez la liste sans null:

var denullified = myList.Where(l => l != null);
if(denullified.Count() != denullified.Distinct().Count()) ...
4
répondu zmbq 2013-06-06 11:06:41

EDIT ma première tentative est nulle car elle n'est pas différée.

Au lieu de cela,

var duplicates = myList
    .Where(item => item != null)
    .GroupBy(item => item)
    .Any(g => g.Skip(1).Any());

mauvaise mise en œuvre supprimé.

1
répondu Jodrell 2013-06-06 13:17:34