LINQ查询以查找列表中的项是否包含在另一个列表中

cjo*_*hns 50 c# linq

我有以下代码:

List<string> test1 = new List<string> { "@bob.com", "@tom.com" };
List<string> test2 = new List<string> { "joe@bob.com", "test@sam.com" };
Run Code Online (Sandbox Code Playgroud)

我需要删除test2中有@ bob.com或@ tom.com的人.

我试过的是这个:

bool bContained1 = test1.Contains(test2);
bool bContained2 = test2.Contains(test1);
Run Code Online (Sandbox Code Playgroud)

bContained1 = false但是bContained2 = true.我宁愿不遍历每个列表,而是使用Linq查询来检索数据.bContained1与我在下面创建的Linq查询的条件相同:

List<string> test3 = test1.Where(w => !test2.Contains(w)).ToList();
Run Code Online (Sandbox Code Playgroud)

上面的查询适用于完全匹配但不是部分匹配.

我查看了其他查询,但我可以找到与Linq的近似比较.任何想法或任何你可以指向我的地方都会有很大的帮助.

Gis*_*mby 69

var test2NotInTest1 = test2.Where(t2 => test1.Count(t1 => t2.Contains(t1))==0);
Run Code Online (Sandbox Code Playgroud)

根据蒂姆的建议更快的版本:

var test2NotInTest1 = test2.Where(t2 => !test1.Any(t1 => t2.Contains(t1)));
Run Code Online (Sandbox Code Playgroud)

  • `Count(...)== 0`可以替换为'Any`或`All`(取决于你希望你的逻辑结构如何),这样会更有效率,因为一旦找到它就可以停止搜索.另外,考虑使用`EndsWith`而不是`Contains`,否则,例如`@ bob.com`过滤器将消除`joe @ bob.com.some.other.com`. (9认同)

Tim*_* S. 11

var output = emails.Where(e => domains.All(d => !e.EndsWith(d)));
Run Code Online (Sandbox Code Playgroud)

或者如果您愿意:

var output = emails.Where(e => !domains.Any(d => e.EndsWith(d)));
Run Code Online (Sandbox Code Playgroud)


Roh*_*pta 10

bool doesL1ContainsL2 = l1.Intersect(l2).Count() == l2.Count;
Run Code Online (Sandbox Code Playgroud)

L1和L2都是 List<T>

  • 这个答案是不正确的,因为OP也想检查部分匹配。仅当“l1”完全被“l2”覆盖时,此答案才有效。因此,假设“l2”中存在“@bob.com”,但不存在“@tom.com”。“doesL1ContainsL2”的结果将为“false”。这不是OP想要的。 (2认同)
  • @hastrb,有些人在看到问题标题后来到这里。 (2认同)

wal*_*her 5

这里不需要像这样使用 Linq,因为已经存在一个扩展方法来为您执行此操作。

Enumerable.Except<TSource>

http://msdn.microsoft.com/en-us/library/bb336390.aspx

您只需要创建自己的比较器即可根据需要进行比较。