web-dev-qa-db-fra.com

Évitez d’ajouter des éléments en double à une liste C #

string[] lines3 = new string[100];
List<string> lines2 = new List<string>();
lines3 = Regex.Split(s1, @"\s*,\s*");

if (!lines2.Contains(lines3.ToString()))
{
    lines2.AddRange(lines3.Distinct().ToArray());
}

J'ai vérifié tous les espaces, etc., mais j'obtiens toujours des valeurs en double dans mes lignes2 List

Je dois supprimer mes doublons ici 

18
vini

Votre ce chèque: 

if (!lines2.Contains(lines3.ToString()))

est invalide. Vous vérifiez si votre lines2 contient System.String[] puisque lines3.ToString() vous le donnera. Vous devez vérifier si un élément de lines3 existe dans lines2 ou non. 

Vous pouvez itérer chaque élément dans lines3 pour vérifier s’il existe dans le lines2, puis l’ajouter. Quelque chose comme. 

foreach (string str in lines3)
{
    if (!lines2.Contains(str))
        lines2.Add(str);
}

Ou si votre lines2 est une liste vide, vous pouvez simplement ajouter les valeurs distinctes lines3 à la liste, comme suit: 

lines2.AddRange(lines3.Distinct());

alors votre lines2 contiendra des valeurs distinctes. 

25
Habib

Vous pouvez utiliser Enumerable.Except pour obtenir des éléments distincts de lignes3 qui ne figurent pas dans lignes2:

lines2.AddRange(lines3.Except(lines2));

Si lines2 contient tous les éléments de lines3, rien ne sera ajouté. BTW en interne Except utilise Set<string> pour obtenir des éléments distincts de la deuxième séquence et pour vérifier les éléments présents dans la première séquence. Donc, c'est assez rapide.

33
Sergey Berezovskiy

Utilisez un HashSet<string> au lieu d'un List<string>. Il est prêt à améliorer les performances, car vous n'avez pas besoin de vérifier les éléments. La collection le gérera pour vous. C'est la différence entre un list et un set. Comme échantillon:

HashSet<string> set = new HashSet<string>();

set.Add("a");
set.Add("a");
set.Add("b");
set.Add("c");
set.Add("b");
set.Add("c");
set.Add("a");
set.Add("d");
set.Add("e");
set.Add("e");

var total = set.Count;

Total est 5 et les valeurs sont a, b, c, d, e.

L'implémentation de List<T> ne vous donne pas nativelly. Vous pouvez le faire, mais vous devez fournir ce contrôle. Pour l'échantillon, ce extension method:

public static class CollectionExtensions
{
    public static void AddItem<T>(this List<T> list, T item)
    {
       if (!list.Contains(item))
       {
          list.Add(item);
       }
    }
}

et l'utiliser:

var list = new List<string>();
list.AddItem(1);
list.AddItem(2);
list.AddItem(3);
list.AddItem(2);
list.AddItem(4);
list.AddItem(5);
22
Felipe Oriani

Si vous ne voulez pas de doublons dans une liste, utilisez un HashSet . De cette façon, toute personne lisant votre code comprendra clairement votre intention et vous aurez moins de code à écrire puisque HashSet gère déjà ce que vous essayez de faire.

3
Ian Mercer

Vous pouvez utiliser une simple Union + Distinct:

var lines = lines2.Union(lines3).Distinct();

Cela ajoutera tous les éléments de la deuxième liste à la première liste, puis renverra toutes les chaînes uniques de la liste combinée. Peu de chances de bien fonctionner avec de grandes listes, mais c'est simple.

Référence: http://msdn.Microsoft.com/en-us/library/bb341731.aspx

3
Tieson T.

Si votre chèque avait fonctionné, il aurait soit ajouté tous les éléments, soit aucun. Cependant, l'appel de la méthode ToString sur un tableau renvoie le nom du type de données, pas le contenu du tableau, et la méthode Contains ne peut rechercher qu'un seul élément, pas une collection d'éléments de toute façon.

Vous devez vérifier chaque chaîne du tableau:

string[] lines3;
List<string> lines2 = new List<string>();

lines3 = Regex.Split(s1, @"\s*,\s*");

foreach (string s in lines3) {
  if (!lines2.Contains(s)) {
    lines2.Add(s);
  }
}

Toutefois, si vous commencez avec une liste vide, vous pouvez utiliser la méthode Distinct pour supprimer les doublons. Vous n'avez besoin que d'une seule ligne de code:

List<string> lines2 = Regex.Split(s1, @"\s*,\s*").Distinct().ToList();
1
Guffa

Si vous souhaitez enregistrer des valeurs distinctes dans une collection, vous pouvez essayer HashSet Class . Il supprimera automatiquement les valeurs en double et économisera votre temps de codage. :)

1
Erxin

En prenant l’allusion de #Felipe Oriani, j’ai réalisé l’extension que je voudrais partager ici pour de bon.

public static class CollectionExtension
{
    public static void AddUniqueItem<T>(this List<T> list, T item, bool throwException)
    {
        if (!list.Contains(item))
        {
            list.Add(item);
        }
        else if(throwException)
        {
            throw new InvalidOperationException("Item already exists in the list");
        }
    }
    public static bool IsUnique<T>(this List<T> list, IEqualityComparer<T> comparer)
    {
        return list.Count == list.Distinct(comparer).Count();
    }
    public static bool IsUnique<T>(this List<T> list)
    {
        return list.Count == list.Distinct().Count();
    }
}
0
Kasim Husaini

pas un bon moyen, mais un peu de solution miracle,.

bool containsKey;
string newKey;

    public void addKey(string newKey){

         foreach(string key in MyKeys){
           if(key == newKey){
             containsKey = true;
          }
         }

      if(!containsKey){
       MyKeys.add(newKey);
     }else{
       containsKey = false;
     }

    }
0
Amir Javed

Utilisez une HashSet avec votre List:

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

public void addToList(string s) {
    if (myHashSet.Add(s)) {
        myList.Add(s);
    }
}

myHashSet.Add(s) retournera true si s n'y est pas.

0
Phạm Tuấn Anh

utiliser HashSet c'est mieux

jetez un oeil ici: http://www.dotnetperls.com/hashset

0
danvasiloiu