Определите, появляется ли строка более одного раза в массиве строк (C #) - PullRequest
1 голос
/ 06 сентября 2011

У меня есть массив строк, т. Е.

string [] letters = { "a", "a", "b", "c" };

Мне нужно найти способ определить, появляется ли какая-либо строка в массиве более одного раза. Я думал, что лучший способ - создать новый массив строк без рассматриваемой строки и использовать Contains,

foreach (string letter in letters)
{
    string [] otherLetters = //?
    if (otherLetters.Contains(letter))
    {
        //etc.     
    }
}

но я не могу понять, как. Если у кого-то есть решение для этого или лучший подход, пожалуйста, ответьте.

Ответы [ 4 ]

10 голосов
/ 06 сентября 2011

Самый простой способ - использовать GroupBy:

var lettersWithMultipleOccurences = letters.GroupBy(x => x)
                                           .Where(g => g.Count() > 1)
                                           .Select(g => g.Key);

Это сначала сгруппирует ваш массив, используя буквы в качестве ключей. Затем он возвращает только те группы с несколькими записями и возвращает ключ этих групп. В результате у вас будет IEnumerable<string>, содержащий все буквы, которые встречаются более одного раза в исходном массиве. В вашем примере это только «а».

Осторожно: поскольку LINQ реализован с использованием отложенного выполнения, при перечислении lettersWithMultipleOccurences несколько раз будет выполняться группировка и фильтрация несколько раз. Чтобы избежать этого, позвоните ToList() по результату:

var lettersWithMultipleOccurences = letters.GroupBy(x => x)
                                           .Where(g => g.Count() > 1)
                                           .Select(g => g.Key).
                                           .ToList();

lettersWithMultipleOccurences теперь будет иметь тип List<string>.

4 голосов
/ 06 сентября 2011

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

if (letters.Distinct().Count() == letters.Count()) {
    // no duplicates
}

Enumerable.Distinct удаляет дубликаты. Таким образом, letters.Distinct() вернет три элемента в вашем примере.

1 голос
/ 06 сентября 2011

HashSet даст вам хорошую производительность:

HashSet<string> hs = new HashSet<string>();
foreach (string letter in letters)
{
    if (hs.Contains(letter))
    {
        //etc. more as once     
    }
    else
    {
           hs.Add(letter);
    }
}
1 голос
/ 06 сентября 2011

Создайте HashSet из массива и сравните их размеры:

var set = new HashSet(letters);
bool hasDoubleLetters = set.Size == letters.Length;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...