LINQy检查集合中的任何对象是否具有相同属性值的方法

时间:2023-02-07 22:34:23

I have a class Agent with a property Id

我有一个具有属性Id的类代理

Given a collection of Agents I need to check if any of them have duplicate Ids.

给定一组Agent,我需要检查它们中是否有任何重复的ID。

I am currently doing this with a hash table but am trying to get Linq-ified, what's a good way of doing this?

我目前正在使用哈希表执行此操作,但我正在尝试使用Linq-ified,这样做的好方法是什么?

6 个解决方案

#1


11  

Similar to Y Low's approach,

与Y Low的方法类似,

Edited:

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

 foreach (var agent in duplicates)
 {
         Console.WriteLine(agent.Key.ToString());
 }

#2


3  

For what it's worth, I just compared the two methods we've struck upon in this thread. First I defined a helper class:

对于它的价值,我只是比较了我们在这个帖子中遇到的两种方法。首先我定义了一个帮助器类:

public class Foo
{
    public int ID;
}

... and then made a big list of instances with a random ID:

...然后用随机ID制作一个大的实例列表:

var list = new List<Foo>();

var r = new Random();

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

... and lastly, timed the code:

......最后,定时代码:

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);

Here's one output:

这是一个输出:

False

59392129

False

168151

So I think it's safe to say that grouping and then comparing the count of groups to the count of items is way, way faster than doing a brute-force "nested Any" comparison.

所以我认为可以说,分组然后将组的数量与项目数量进行比较是比进行暴力“嵌套任意”比较更快的方式。

#3


2  

My take (no counting!):

我的看法(不计算!):

var duplicates = agents
  .GroupBy(a => a.ID)
  .Where(g => g.Skip(1).Any());

#4


1  

foreach(var agent in Agents) {
    if(Agents.Count(a => a.ID == agent.ID) > 1)
        Console.WriteLine("Found: {0}", agent.ID);
}

#5


1  

bool b = list.Any(i => list.Any(j => j.ID == i.ID && j != i));

That's a bit of a brute-force approach but it works. There might be a smarter way to do it using the Except() extension method.

这是一种蛮力的方法,但它的工作原理。使用Except()扩展方法可能有更聪明的方法。

Edit: You didn't actually say that you needed to know which items are "duplicated", only that you needed to know whether any where. This'll do the same thing except give you a list you can iterate over:

编辑:你实际上并没有说你需要知道哪些项目是“重复的”,只是你需要知道是否有任何地方。这会做同样的事情,除了给你一个你可以迭代的列表:

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

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

I like the grouping approach too (group by ID and find the groups with count > 1).

我也喜欢分组方法(按ID分组并查找count> 1的组)。

#6


0  

this is how i would do it without the need to do group-by in one line:

这就是我如何做到这一点,而不需要在一行中进行分组:

 List<Agent> duplicates = new HashSet<Agent>(agents.Where(c => agents.Count(x => x.ID == c.ID) > 1)).ToList();

#1


11  

Similar to Y Low's approach,

与Y Low的方法类似,

Edited:

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

 foreach (var agent in duplicates)
 {
         Console.WriteLine(agent.Key.ToString());
 }

#2


3  

For what it's worth, I just compared the two methods we've struck upon in this thread. First I defined a helper class:

对于它的价值,我只是比较了我们在这个帖子中遇到的两种方法。首先我定义了一个帮助器类:

public class Foo
{
    public int ID;
}

... and then made a big list of instances with a random ID:

...然后用随机ID制作一个大的实例列表:

var list = new List<Foo>();

var r = new Random();

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

... and lastly, timed the code:

......最后,定时代码:

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);

Here's one output:

这是一个输出:

False

59392129

False

168151

So I think it's safe to say that grouping and then comparing the count of groups to the count of items is way, way faster than doing a brute-force "nested Any" comparison.

所以我认为可以说,分组然后将组的数量与项目数量进行比较是比进行暴力“嵌套任意”比较更快的方式。

#3


2  

My take (no counting!):

我的看法(不计算!):

var duplicates = agents
  .GroupBy(a => a.ID)
  .Where(g => g.Skip(1).Any());

#4


1  

foreach(var agent in Agents) {
    if(Agents.Count(a => a.ID == agent.ID) > 1)
        Console.WriteLine("Found: {0}", agent.ID);
}

#5


1  

bool b = list.Any(i => list.Any(j => j.ID == i.ID && j != i));

That's a bit of a brute-force approach but it works. There might be a smarter way to do it using the Except() extension method.

这是一种蛮力的方法,但它的工作原理。使用Except()扩展方法可能有更聪明的方法。

Edit: You didn't actually say that you needed to know which items are "duplicated", only that you needed to know whether any where. This'll do the same thing except give you a list you can iterate over:

编辑:你实际上并没有说你需要知道哪些项目是“重复的”,只是你需要知道是否有任何地方。这会做同样的事情,除了给你一个你可以迭代的列表:

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

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

I like the grouping approach too (group by ID and find the groups with count > 1).

我也喜欢分组方法(按ID分组并查找count> 1的组)。

#6


0  

this is how i would do it without the need to do group-by in one line:

这就是我如何做到这一点,而不需要在一行中进行分组:

 List<Agent> duplicates = new HashSet<Agent>(agents.Where(c => agents.Count(x => x.ID == c.ID) > 1)).ToList();