Со следующими данными
string[] data = { "a", "a", "b" };
Я очень хотел бы найти дубликаты и получить этот результат:
a
Я попробовал следующий код
var a = data.Distinct().ToList();
var b = a.Except(a).ToList();
очевидно, это не работало, я вижу то, что происходит выше, но я не уверен, как зафиксировать его.
Когда во время выполнения нет проблем, вы можете использовать
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();
Используйте группировку по материалу, производительность этих методов достаточно хорошая. Единственное беспокойство - большие накладные расходы на память, если вы работаете с большими наборами данных.
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)
. Затраты на каждую операцию несколько высоки, но они должны соответствовать почти линейной производительности.
Сортировка данных, итерация по ним и запоминание последнего элемента. Если текущий элемент совпадает с последним, то это дубликат. Это может быть легко реализовано либо итеративно, либо с помощью лямбда-выражения за время O(n*log(n)).