在C#中求两个列表的交集

76
我有两个列表:
  List<int> data1 = new List<int> {1,2,3,4,5};
  List<string> data2 = new List<string>{"6","3"};

我想做类似于

var newData = data1.intersect(data2, lambda expression);
lambda表达式应该在data1[index].ToString() == data2[index]为真时返回true。

1
可能是重复的问题:检查两个List<int>中是否有相同的数字 - Joshua Drake
1
@JoshuaDrake 我不认为这是一个重复的问题;那个问题没有考虑使用lambda来自定义相等性判断。 - ApproachingDarknessFish
@ValekHalfHeart 我可能应该把它标记为相关的,我不知何故错过了这个问题中数据类型的差异。 - Joshua Drake
4个回答

105

您需要先转换data1,即在每个元素上调用ToString()

如果希望返回字符串,请使用此方法。

List<int> data1 = new List<int> {1,2,3,4,5};
List<string> data2 = new List<string>{"6","3"};

var newData = data1.Select(i => i.ToString()).Intersect(data2);

如果你想返回整数,请使用这个函数。

List<int> data1 = new List<int> {1,2,3,4,5};
List<string> data2 = new List<string>{"6","3"};

var newData = data1.Intersect(data2.Select(s => int.Parse(s));
请注意,如果不是所有的字符串都是数字,这将抛出异常。因此,您可以首先执行以下操作进行检查:
int temp;
if(data2.All(s => int.TryParse(s, out temp)))
{
    // All data2 strings are int's
}

15

如果您有对象而不是结构体(或字符串),那么您需要先交叉它们的键,然后选择这些键对应的对象:

var ids = list1.Select(x => x.Id).Intersect(list2.Select(x => x.Id));
var result = list1.Where(x => ids.Contains(x.Id));

1
好的回答。简单明了。 - Senura Dissanayake

8

从性能角度来看,如果两个列表包含数量显著不同的元素,则可以尝试以下方法(使用条件运算符?:):

1.首先需要声明一个转换器:

Converter<string, int> del = delegate(string s) { return Int32.Parse(s); };

2.接着您可以使用条件运算符:

var r = data1.Count > data2.Count ?
 data2.ConvertAll<int>(del).Intersect(data1) :
 data1.Select(v => v.ToString()).Intersect(data2).ToList<string>().ConvertAll<int>(del);

您需要将较短列表的元素转换为与较长列表相同的类型。想象一下,如果您的第一个集合包含1000个元素,而第二个集合仅有10个(或者反过来,这并不重要),那么您的执行速度会怎样呢?;-)
由于您希望得到一个List作为结果,在最后一行中,您只需将结果(仅仅是结果)转换回int类型即可。

-4
public static List<T> ListCompare<T>(List<T> List1 , List<T> List2 , string key )
{
    return List1.Select(t => t.GetType().GetProperty(key).GetValue(t))
                .Intersect(List2.Select(t => t.GetType().GetProperty(key).GetValue(t))).ToList();
}

5
请提供适当的解释,并附带代码。即使是代码中的注释也可以。同时,请理解代码样式可以提高答案的可读性。如果您限制每行代码不超过80个字符,则答案将不需要滚动条。此外,您的答案可能会有一长串函数调用链,为了更好的理解,可以在代码中进行解释。 - Vasif
为什么要使用反射?我们已经知道了列表类型。特别是,我们知道每个元素的类型,它们要么是整数,要么是字符串。通过反射查询列表中每个元素的值纯属过度杀伤力,会使这个问题变得非常复杂。 - MakePeaceGreatAgain

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