LINQy способ проверить, имеют ли какие-либо объекты в коллекции одинаковое значение свойства - PullRequest
7 голосов
/ 23 ноября 2008

У меня есть класс Agent с идентификатором свойства

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

В настоящее время я делаю это с помощью хеш-таблицы, но пытаюсь получить Linq-ified, каков хороший способ сделать это?

Ответы [ 6 ]

11 голосов
/ 23 ноября 2008

Аналогично подходу Лоу,

Отредактировано:

 var duplicates = agents.GroupBy(a => a.ID).Where(a=>a.Count() > 1);

 foreach (var agent in duplicates)
 {
         Console.WriteLine(agent.Key.ToString());
 }
3 голосов
/ 24 ноября 2008

Для чего бы это ни стоило, я только что сравнил два метода, с которыми мы столкнулись в этой теме. Сначала я определил вспомогательный класс:

public class Foo
{
    public int ID;
}

... а затем составили большой список экземпляров со случайным идентификатором:

var list = new List<Foo>();

var r = new Random();

for (int i = 0; i < 10000; i++) list.Add(new Foo { ID = r.Next() });

... и, наконец, рассчитал код:

var sw = new Stopwatch();
sw.Start();
bool b = list.Any(i => list.Where(j => i != j).Any(j => j.ID == i.ID));
Console.WriteLine(b);
Console.WriteLine(sw.ElapsedTicks);

sw.Reset();
sw.Start();
b = (list.GroupBy(i => i.ID).Count() != list.Count);
Console.WriteLine(b);
Console.WriteLine(sw.ElapsedTicks);

Вот один из выводов:

Ложная

59392129

Ложная

168151

Так что я думаю, что можно с уверенностью сказать, что группировка, а затем сравнение количества групп с количеством элементов - это путь на путь быстрее, чем сравнение методом "вложенной Любой" методом грубой силы.

2 голосов
/ 23 ноября 2008

Мой дубль (не считая!):

var duplicates = agents
  .GroupBy(a => a.ID)
  .Where(g => g.Skip(1).Any());
1 голос
/ 23 ноября 2008
bool b = list.Any(i => list.Any(j => j.ID == i.ID && j != i));

Это немного грубый подход, но он работает. Возможно, есть более разумный способ сделать это, используя метод расширения Except ().

Редактировать: Вы на самом деле не сказали, что вам нужно знать , какие элементы «дублированы», только то, что вам нужно было знать, где-либо. Это будет делать то же самое, за исключением того, что вы получите список, который вы можете перебрать:

list.Where (i => list.Any (j => j.ID == i.ID && j! = I))

Мне также нравится подход группирования (группируйте по ID и находите группы с количеством> 1).

1 голос
/ 23 ноября 2008
foreach(var agent in Agents) {
    if(Agents.Count(a => a.ID == agent.ID) > 1)
        Console.WriteLine("Found: {0}", agent.ID);
}
0 голосов
/ 20 сентября 2016

это то, как я бы сделал это без необходимости группировать в одну строку:

 List<Agent> duplicates = new HashSet<Agent>(agents.Where(c => agents.Count(x => x.ID == c.ID) > 1)).ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...