【问题标题】:What is the best way to compute intersection and difference of 2 sets?计算两组的交集和差异的最佳方法是什么?
【发布时间】:2011-09-23 13:54:46
【问题描述】:

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

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

有没有快速的方法来做到这一点?

【问题讨论】:

  • 不,只是我自己的方法似乎有一些开销。我独立生成每个列表,每次搜索另一个集合中的元素。
  • 您是否查看过您正在使用的 set 类的文档?

标签: c# .net list set


【解决方案1】:
var requirement1 = list1.Intersect(list2);
var requirement2 = list1.Except(list2);
var requirement3 = list2.Except(list1);

对于您的List<string>,这将是您所需要的。如果您正在为自定义类执行此操作,并且您正在寻找参考比较以外的其他内容,那么您需要确保该类正确覆盖了EqualsGetHashCode。或者,您可以为上述方法的重载提供IEqualityComparer<YourType>

编辑:

好的,现在您已经在 cmets 中指出它不是字符串列表,而是 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();
     }
}

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

list1.Intersect(list2, customComparerInstance);

编辑:现在您又移动了条形图,这一次问题涉及两个不同的类。为此,您将考虑使用连接操作,一个是内部的,另一个是外部的。

如果是

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

class Class2
{
    public string Bar { get; set; }
}

你可以写

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;

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

【讨论】:

  • 嗯...我几乎就是这样做的(实际上我需要从每个列表中选择键)。只是觉得有更快的方法
  • @Poma,这些 Linq 方法已经相当优化,但是如果您仍然需要从最小的 Linq 开销下摆脱出来,您可以自己处理自己的实现,但我不建议这样做,除非这是真正的性能瓶颈。
  • 好的,会用这个。我只是认为有一种方法可以在单个循环中计算所有 3 个列表。
  • 刚刚注意到列表由不同的类组成,所以我不能使用这些扩展。我已经更新了我的问题。
猜你喜欢
  • 2020-11-13
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 2019-09-18
  • 2010-12-15
  • 1970-01-01
相关资源
最近更新 更多