计算两组交集和差异的最佳方法是什么?

Pom*_*oma 2 .net c# list set

我有2个列表,List<Class1>List<Class2>通过相同的属性Class1.KeyClass2.Key(字符串)进行比较,我想写一个函数,将产生3个列表

  1. List<Class1> 两个列表中都存在的元素
  2. List<Class1> 仅存在于第一个列表中的元素
  3. List<Class2> 仅存在于第二个列表中的元素

有快速的方法吗?

Ant*_*ram 10

var requirement1 = list1.Intersect(list2);
var requirement2 = list1.Except(list2);
var requirement3 = list2.Except(list1);
Run Code Online (Sandbox Code Playgroud)

对于您而言List<string>,这将是您所需要的一切.如果您正在为自定义类执行此操作,并且您正在寻找除引用比较之外的其他内容,那么您需要确保该类正确地覆盖Equals并且GetHashCode.或者,您可以提供IEqualityComparer<YourType>上述方法的重载.

编辑:

好的,现在你已经在评论中指出它不是一个字符串列表,它是一个List<MyObject>.在这种情况下,重载Equals/GetHashCode的(如果你的钥匙应该唯一识别这些类所有的时间,你可以访问源代码)或提供的IEqualityComparer实现(仍然涉及的Equals/GetHashCode的,使用这个如果比较是唯一的这些需要或者如果您无权访问MyObject源代码.

例如:

class MyObjectComparer : IEqualityComparer<MyObject>
{
     public bool Equals(MyObject x, MyObject y)
     {
          // implement appropriate comparison of x and y, check for nulls, etc 
     }

     public int GetHashCode(MyObject obj)
     {
          // validate if necessary
          return obj.KeyProperty.GetHashCode();
     }
}
Run Code Online (Sandbox Code Playgroud)

如果您使用了这样的自定义相等比较器,则调用上述方法

list1.Intersect(list2, customComparerInstance);
Run Code Online (Sandbox Code Playgroud)

编辑:现在你再次移动了这个栏,这次问题涉及两个不同的类.为此,您可以考虑使用连接操作,一个是内部操作,另一个是外部操作.

如果是

class Class1
{
    public string Foo { get; set; } 
}

class Class2
{
    public string Bar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

你可以写

var intersect = from item1 in list1
                join item2 in list2
                on item1.Foo equals item2.Bar
                select item1;

var except1 = from item1 in list1
                join item2 in list2
                on item1.Foo equals item2.Bar into gj
                from item2 in gj.DefaultIfEmpty()
                where item2 == null
                select item1;
Run Code Online (Sandbox Code Playgroud)

要获取list2中的项而不匹配list1中的*对象,只需颠倒except1查询中列表/项的顺序即可.