Как найти все дубликаты из списка <string & gt ;?

У меня есть List<string>, в котором дублируются некоторые слова. Мне нужно найти все слова, которые являются дубликатами.

Есть ли уловка, чтобы получить их все?

104 голоса | спросил Steven Spielberg 2 Jpm1000000pmSun, 02 Jan 2011 15:02:54 +030011 2011, 15:02:54

8 ответов


0

В .NET Framework 3.5 и выше вы можете использовать Enumerable.GroupBy, который возвращает перечислимые повторяющиеся ключи, а затем отфильтровывает любые из перечислимых объектов, имеющих число <= 1, затем выберите их ключи, чтобы вернуться к единственному перечисляемому:

var duplicateKeys = list.GroupBy(x => x)
                        .Where(group => group.Count() > 1)
                        .Select(group => group.Key);
ответил Giuseppe Ottaviano 2 Jpm1000000pmSun, 02 Jan 2011 15:10:58 +030011 2011, 15:10:58
0

Если вы используете LINQ, вы можете использовать следующий запрос:

var duplicateItems = from x in list
                     group x by x into grouped
                     where grouped.Count() > 1
                     select grouped.Key;

или, если вы предпочитаете без синтаксического сахара:

var duplicateItems = list.GroupBy(x => x).Where(x => x.Count() > 1).Select(x => x.Key);

Это группирует все элементы, которые являются одинаковыми, а затем фильтрует только те группы с более чем одним элементом. Наконец, он выбирает только ключ из этих групп, поскольку вам не нужен счетчик.

Если вы предпочитаете не использовать LINQ, вы можете использовать этот метод расширения:

public void SomeMethod {
    var duplicateItems = list.GetDuplicates();
    …
}

public static IEnumerable<T> GetDuplicates<T>(this IEnumerable<T> source) {
    HashSet<T> itemsSeen = new HashSet<T>();
    HashSet<T> itemsYielded = new HashSet<T>();

    foreach (T item in source) {
        if (!itemsSeen.Add(item)) {
            if (itemsYielded.Add(item)) {
                yield return item;
            }
        }
    }
}

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

ответил ICR 2 Jpm1000000pmSun, 02 Jan 2011 17:56:01 +030011 2011, 17:56:01
0

и без LINQ:

string[] ss = {"1","1","1"};

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

foreach (var s in ss)
{
   if (!myList.Contains(s))
      myList.Add(s);
   else
      duplicates.Add(s);
}

// show list without duplicates 
foreach (var s in myList)
   Console.WriteLine(s);

// show duplicates list
foreach (var s in duplicates)
   Console.WriteLine(s);
ответил evilone 2 Jpm1000000pmSun, 02 Jan 2011 15:13:48 +030011 2011, 15:13:48
0

Если вы ищете более общий метод:

public static List<U> FindDuplicates<T, U>(this List<T> list, Func<T, U> keySelector)
    {
        return list.GroupBy(keySelector)
            .Where(group => group.Count() > 1)
            .Select(group => group.Key).ToList();
    }

РЕДАКТИРОВАТЬ: Вот пример:

public class Person {
    public string Name {get;set;}
    public int Age {get;set;}
}

List<Person> list = new List<Person>() { new Person() { Name = "John", Age = 22 }, new Person() { Name = "John", Age = 30 }, new Person() { Name = "Jack", Age = 30 } };

var duplicateNames = list.FindDuplicates(p => p.Name);
var duplicateAges = list.FindDuplicates(p => p.Age);

foreach(var dupName in duplicateNames) {
    Console.WriteLine(dupName); // Will print out John
}

foreach(var dupAge in duplicateAges) {
    Console.WriteLine(dupAge); // Will print out 30
}
ответил Mauricio Ramalho 7 MonEurope/Moscow2015-12-07T13:47:50+03:00Europe/Moscow12bEurope/MoscowMon, 07 Dec 2015 13:47:50 +0300 2015, 13:47:50
0

Использование LINQ, конечно. Приведенный ниже код даст вам словарь элемента в виде строки и количество каждого элемента в вашем списке источников.

var item2ItemCount = list.GroupBy(item => item).ToDictionary(x=>x.Key,x=>x.Count());
ответил Manish Basantani 2 Jpm1000000pmSun, 02 Jan 2011 15:15:14 +030011 2011, 15:15:14
0

Я предполагаю, что каждая строка в вашем списке содержит несколько слов, дайте мне знать, если это неверно.

List<string> list = File.RealAllLines("foobar.txt").ToList();

var words = from line in list
            from word in line.Split(new[] { ' ', ';', ',', '.', ':', '(', ')' }, StringSplitOptions.RemoveEmptyEntries)
            select word;

var duplicateWords = from w in words
                     group w by w.ToLower() into g
                     where g.Count() > 1
                     select new
                     {
                         Word = g.Key,
                         Count = g.Count()
                     }
ответил Thomas Levesque 2 Jpm1000000pmSun, 02 Jan 2011 15:10:13 +030011 2011, 15:10:13
0

Для чего это стоит, вот мой путь:

List<string> list = new List<string>(new string[] { "cat", "Dog", "parrot", "dog", "parrot", "goat", "parrot", "horse", "goat" });
Dictionary<string, int> wordCount = new Dictionary<string, int>();

//count them all:
list.ForEach(word =>
{
    string key = word.ToLower();
    if (!wordCount.ContainsKey(key))
        wordCount.Add(key, 0);
    wordCount[key]++;
});

//remove words appearing only once:
wordCount.Keys.ToList().FindAll(word => wordCount[word] == 1).ForEach(key => wordCount.Remove(key));

Console.WriteLine(string.Format("Found {0} duplicates in the list:", wordCount.Count));
wordCount.Keys.ToList().ForEach(key => Console.WriteLine(string.Format("{0} appears {1} times", key, wordCount[key])));
ответил Shadow Wizard 2 Jpm1000000pmSun, 02 Jan 2011 15:29:20 +030011 2011, 15:29:20
0
    lblrepeated.Text = ""; 
    string value = txtInput.Text;
    char[] arr = value.ToCharArray();
    char[] crr=new char[1];        
   int count1 = 0;        
    for (int i = 0; i < arr.Length; i++)
    {
        int count = 0;  
        char letter=arr[i];
        for (int j = 0; j < arr.Length; j++)
        {
            char letter3 = arr[j];
                if (letter == letter3)
                {
                    count++;
                }                    
        }
        if (count1 < count)
        {
            Array.Resize<char>(ref crr,0);
            int count2 = 0;
            for(int l = 0;l < crr.Length;l++)
            {
                if (crr[l] == letter)
                    count2++;                    
            }


            if (count2 == 0)
            {
                Array.Resize<char>(ref crr, crr.Length + 1);
                crr[crr.Length-1] = letter;
            }

            count1 = count;               
        }
        else if (count1 == count)
        {
            int count2 = 0;
            for (int l = 0; l < crr.Length; l++)
            {
                if (crr[l] == letter)
                    count2++;
            }


            if (count2 == 0)
            {
                Array.Resize<char>(ref crr, crr.Length + 1);
                crr[crr.Length - 1] = letter;
            }

            count1 = count; 
        }
    }

    for (int k = 0; k < crr.Length; k++)
        lblrepeated.Text = lblrepeated.Text + crr[k] + count1.ToString();
ответил kittu 7 12011vEurope/Moscow11bEurope/MoscowMon, 07 Nov 2011 09:07:47 +0400 2011, 09:07:47

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132