Лямбда-выражение, чтобы найти разницу - PullRequest
5 голосов
/ 29 июня 2010

со следующими данными

string[] data = { "a", "a", "b" };

Я бы очень хотел найти дубликаты и получить такой результат:

a

Я попробовал следующий код

var a = data.Distinct().ToList();
var b = a.Except(a).ToList();

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

Ответы [ 3 ]

11 голосов
/ 29 июня 2010

Если во время выполнения нет проблем, вы можете использовать

var duplicates = data.Where(s => data.Count(t => t == s) > 1).Distinct().ToList();

Старый добрый O (n ^ n) =)

Редактировать: Теперь для лучшего решения,=) Если вы определяете новый метод расширения, например

static class Extensions
{        

    public static IEnumerable<T> Duplicates<T>(this IEnumerable<T> input)
    {
        HashSet<T> hash = new HashSet<T>();
        foreach (T item in input)
        {
            if (!hash.Contains(item))
            {
                hash.Add(item);
            }
            else
            {
                yield return item;
            }
        }
    }
}

, вы можете использовать

var duplicates = data.Duplicates().Distinct().ToArray();
5 голосов
/ 29 июня 2010

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

from g in (from x in data group x by x)
where g.Count() > 1 
select g.Key;

- ИЛИ если вы предпочитаете методы расширения

data.GroupBy(x => x)
    .Where(x => x.Count() > 1)
    .Select(x => x.Key)

Где Count() == 1 это ваши отличительные элементы, а где Count() > 1 это один или несколько дубликатов.

Поскольку LINQ довольно ленив, если вы не хотите пересматривать свои вычисления, вы можете сделать это:

var g = (from x in data group x by x).ToList(); // grouping result
// duplicates
from x in g
where x.Count() > 1 
select x.Key;
// distinct
from x in g
where x.Count() == 1 
select x.Key;

При создании группировки будет создан набор наборов. Предполагая, что это набор со вставкой O(1), время выполнения группы при заходе на посадку составляет O(n). Затраты на каждую операцию несколько высоки, но они должны быть равны почти линейным показателям.

1 голос
/ 29 июня 2010

Сортировка данных, итерация по ним и запоминание последнего элемента.Когда текущий элемент совпадает с последним, его дубликат.Это может быть легко реализовано либо итеративно, либо с использованием лямбда-выражения за O (n * log (n)) времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...