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

时间:2008-11-23 02:20:38

标签: c# linq

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

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

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

6 个答案:

答案 0 :(得分:11)

与Y Low的方法类似,

<强>编辑:

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

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

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:2)

我的看法(不计算在内):

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

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

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

list.Where(i =&gt; list.Any(j =&gt; j.ID == i.ID&amp;&amp; j!= i))

我也喜欢分组方法(按ID分组并找到计数> 1的组。)

答案 5 :(得分:0)

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

NAME := MySuperProgram
BDIR := bin
ODIR := obj
SRC := $(wildcard src/*.cpp)
OBJ := $(SRC:src/%.cpp=$(ODIR)/%.o)
CXXFLAGS := -W -Wall -Werror

.PHONY: all debug clean fclean re

all: $(NAME)

debug: CXXFLAGS += -DDEBUG -g
debug:all

$(NAME): $(OBJ) | $(BDIR)
    $(CXX) $(CXXFLAGS) $^ -o $(BDIR)/$@

$(ODIR)/%.o: src/%.cpp | $(ODIR)
    $(CXX) $(CXXFLAGS) -c -o $@ $<

$(ODIR) $(BDIR):
    @mkdir -p $@

clean:
    $(RM) -r $(ODIR)

fclean: clean
    $(RM) -r $(BDIR)

re: fclean all