it-swarm.com.ru

Избегайте добавления повторяющихся элементов в список 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());
}

Я проверил все пробелы и т.д., Но я все еще получаю повторяющиеся значения в моих строках2 List

Я должен удалить свои дубликаты здесь 

18
vini

Ваш этот чек: 

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

является недействительным. Вы проверяете, содержит ли lines2System.String[], так как lines3.ToString() даст вам это. Вам необходимо проверить, существует ли элемент из lines3 в lines2 или нет. 

Вы можете выполнить итерацию каждого элемента в lines3, проверить, существует ли он в lines2, а затем добавить его. Что-то вроде. 

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

Или, если ваш lines2 является каким-либо пустым списком, вы можете просто добавить различные значения lines3 в список, например: 

lines2.AddRange(lines3.Distinct());

тогда ваш lines2 будет содержать различные значения. 

25
Habib

Вы можете использовать Enumerable.Except , чтобы получить отдельные элементы из строк3, которых нет в строках2:

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

Если lines2 содержит все элементы из lines3, тогда ничего не будет добавлено. Кстати, внутри Except используется Set<string> для получения различных элементов из второй последовательности и для проверки этих элементов, присутствующих в первой последовательности. Итак, это довольно быстро.

33
Sergey Berezovskiy

Используйте HashSet<string> вместо List<string>. Он подготовлен для повышения производительности, потому что вам не нужно предоставлять проверки для каких-либо предметов. Коллекция справится за вас. В этом разница между list и set. Для образца:

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;

Итого 5, а значения a, b, c, d, e.

Реализация List<T> не дает вам изначально. Вы можете сделать это, но вы должны обеспечить этот контроль. Например, этот extension method:

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

и использовать это:

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

Если вы не хотите дубликатов в списке, используйте HashSet . Таким образом, всем, кто читает ваш код, будет ясно, каково ваше намерение, и у вас будет меньше кода для записи, так как HashSet уже обрабатывает то, что вы пытаетесь сделать.

3
Ian Mercer

Вы можете использовать простой Union + Distinct:

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

Это добавит все элементы из второго списка в первый список, а затем вернет все уникальные строки в объединенном списке. С большими списками вряд ли будет хорошо работать, но все просто.

Ссылка: http://msdn.Microsoft.com/en-us/library/bb341731.aspx

3
Tieson T.

Если бы ваш чек сработал, он либо добавил бы все элементы, либо ни одного вообще. Однако вызов метода ToString в массиве возвращает имя типа данных, а не содержимое массива, а метод Contains может искать только один элемент, а не коллекцию элементов в любом случае.

Вы должны проверить каждую строку в массиве:

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);
  }
}

Однако, если вы начинаете с пустого списка, вы можете использовать метод Distinct, чтобы удалить дубликаты, и вам потребуется только одна строка кода:

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

Если вы хотите сохранить отдельные значения в коллекцию, вы можете попробовать HashSet Class . Это автоматически удалит дублирующиеся значения и сэкономит ваше время кодирования. :)

1
Erxin

Взяв подсказку от #Felipe Oriani, я сделал расширение, которым хотел бы поделиться здесь навсегда.

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

не очень хороший способ, но как бы то ни было, возьмите bool, чтобы проверить, есть ли во всем списке повторяющиеся записи.

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

Используйте HashSet вместе с 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) вернет true, если s в нем не существует.

0
Phạm Tuấn Anh

используйте HashSet лучше

посмотрите здесь: http://www.dotnetperls.com/hashset

0
danvasiloiu