从一个列表中减去另一个通用列表

85

我想从一个列表中删除另一个列表中的一些firmIDs。 我不是很了解linq,但我相当确定我需要使用它。

List<Firm> firms = GetBusinessDevelopmentFirms(database);
List<Firm> trackedFirms = GetAllCLIFirmsBeingTrackedByUser();

var result = firms.Contains(i => trackedFirms.Contains(i.FirmID));

尽管我在类的顶部添加了"using System.Linq;",但最后一行不起作用,系统显示"unknown method Contains(?)"。

我的想法是从所有公司的列表中移除跟踪公司的列表,以查找未跟踪的公司。

希望这样说有意义。

6个回答

154
var result = firms.Except(trackedFirms); // returns all the firms except those in trackedFirms

6
这种方法唯一的问题在于,你指望Firm的实际实例在两个列表中都被包含进去。 - Martin Milan
虽然这并不重要,但应该指出这不是Linq,而是List<T>上的一个现有方法。 - CodingIntrigue
你是对的。但请注意,编译器实际上将linq查询转换为相应的扩展方法。因此它们之间没有太大的区别。另外,OP问题的最后一行暗示了他想要什么。 - Alireza
3
不,您只是在链接到Linq方法,并且是从“List<T>”页面的扩展方法部分链接到它。List<T>没有实例Except方法。如果您选择该页面上的重载之一,则会看到它们定义在System.Linq命名空间中,并且第一个参数是IEnumerable<T>而不是List<T> - Servy
@Servy 你是对的 - 我没有在那个页面上看到扩展图标 :) - CodingIntrigue
显示剩余4条评论

15

根据您提供的代码,我猜测您正在尝试获取与TrackedFirms中对应项目的Firms条目。

List<Firm> results = Firms.Where(f => TrackedFirms.Any(t => t.FirmId == f.FirmId)).ToList();

如果您想要未被跟踪的公司,则应该是:
List<Firm> results = Firms.Where(f => !TrackedFirms.Any(t => t.FirmId == f.FirmId)).ToList();

8
我认为这个应该可行。
var result = firms.Where(x => !trackedFirms.Any(y => x.FirmID == y.FirmID));

从所有的公司中选择一个公司,该公司不在trackedFirms中(至少这是我从您的问题中理解的)。


5

对于您的情况,最好的方法是使用 Except()。但是,如果 List 对象与其他对象不同,则可以使用 All()

firms.Where(x=> trackedFirms.All(y => y.FirmId != x.FirmId)

3

ContainsList<T>的原生方法,它需要你传入一个T。而你需要使用Where方法。

var result = firms.Where(i => trackedFirms.Contains(i.FirmID));

如果您希望result是一个List<T>,则在Where LINQ表达式的末尾添加.ToList()


虽然我的回答与你的问题最相关,但我更喜欢这个答案:https://dev59.com/xmMk5IYBdhLWcg3w3xnq#18895816 如果你只是在他的代码中添加 .ToList(),你将得到相同的结果。或者如果你想知道交集,那么可以使用 Intersect 中的一个结果。这样更精确,也更明显你的目标是什么。我建议接受他们的其中一个答案。祝好运! - Eli Gassert
  1. 这是两个列表的交集,而不是一个列表减去另一个列表。
  2. 您正在为每个项执行线性搜索,这比使用更好的算法要慢得多。
- Servy

0

3
交集不是集合的减法。 - Servy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接