我有一个名为Agent的类,其中有一个属性Id。
给定一组代理,我需要检查是否有任何代理具有重复的Id。
我目前使用哈希表来实现这个功能,但是我正在尝试使用Linq,有没有好的方法可以做到这一点?
类似Y Low的方法,
修订:
var duplicates = agents.GroupBy(a => a.ID).Where(a=>a.Count() > 1);
foreach (var agent in duplicates)
{
Console.WriteLine(agent.Key.ToString());
}
就我所知,我刚刚比较了这个线程中提到的两种方法。首先,我定义了一个帮助类:
public class Foo
{
public int 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() });
最后,对代码进行了计时:
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
因此,我认为将组合后的组数与项目数进行比较要比进行暴力“嵌套任意”比较快得多。
我的看法(不包括计数!):
var duplicates = agents
.GroupBy(a => a.ID)
.Where(g => g.Skip(1).Any());
foreach(var agent in Agents) {
if(Agents.Count(a => a.ID == agent.ID) > 1)
Console.WriteLine("Found: {0}", agent.ID);
}
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 的组)。
这是我在不需要进行分组的情况下如何完成它的方法:
List<Agent> duplicates = new HashSet<Agent>(agents.Where(c => agents.Count(x => x.ID == c.ID) > 1)).ToList();