查找所有相交数据,而不仅仅是唯一值

Pet*_*rdk 12 c# linq intersection

我以为我明白了Intersect,但事实证明我错了.

 List<int> list1 = new List<int>() { 1, 2, 3, 2, 3};
 List<int> list2 = new List<int>() { 2, 3, 4, 3, 4};

 list1.Intersect(list2) =>      2,3

 //But what I want is:
 // =>  2,3,2,3,2,3,3
Run Code Online (Sandbox Code Playgroud)

我可以想办法:

 var intersected = list1.Intersect(list2);
 var list3 = new List<int>();
 list3.AddRange(list1.Where(I => intersected.Contains(I)));
 list3.AddRange(list2.Where(I => intersected.Contains(I)));
Run Code Online (Sandbox Code Playgroud)

在LINQ中有更简单的方法来实现这一目标吗?

我需要说明我不关心结果的顺序.

2,2,2,3,3,3,3也可以.

问题是我在一个非常大的集合中使用它,所以我需要效率.

我们谈论的是对象,而不是整体.这些仅仅是为了简单的例子,但我意识到这可以有所作为.

Eri*_*ert 16

让我们看看我们是否可以精确地描述你想要的东西.如果我错了,请纠正我.你想要的是:列表1的所有元素,按顺序,也出现在列表2中,然后是列表2的所有元素,按顺序,也出现在列表1中.是吗?

似乎很简单.

return list1.Where(x=>list2.Contains(x))
     .Concat(list2.Where(y=>list1.Contains(y)))
     .ToList();
Run Code Online (Sandbox Code Playgroud)

请注意,这对大型列表无效.如果列表每个都有一千个项目,那么这将进行几百万次比较.如果您处于这种情况,那么您希望使用更有效的数据结构来测试成员资格:

list1set = new HashSet(list1);
list2set = new HashSet(list2);

return list1.Where(x=>list2set.Contains(x))
     .Concat(list2.Where(y=>list1set.Contains(y)))
     .ToList();
Run Code Online (Sandbox Code Playgroud)

它只进行了几千次比较,但可能会占用更多内存.

  • 您的LINQ查询不会提供与其他两个查询相同的结果 - 如果元素e在list1中出现n次,而在list2中出现m,则它们包含n*m次,这不是所需的行为. (5认同)
  • *优秀的捕捉*@kvb.我完全错过了,因为在给定的例子中,它们碰巧看起来容易混淆.我将删除不正确的代码.谢谢! (2认同)