【问题标题】:Remove items in one IList<> from another IList<> [duplicate]从另一个 List<> 中删除一个 List<> 中的项目 [重复]
【发布时间】:2012-03-07 08:22:05
【问题描述】:

很抱歉发布这样的基本问题,我是 LINQ 的新手,正在尝试找出最好的方法来做这个,而不是遍历每个 IList

我有 2 个带有自定义 dto 对象的 ILists&lt;&gt;。我想从另一个列表中删除所有匹配的项目。

IList<ItemDTO> list1 = itemsbl.GetBestItems();
IList<ItemDTO> list2 = itemsbl.GetWorstItems();

我需要从list2 中删除list1 中的所有项目。我一直在研究Except() 方法,但显然我需要我的ItemsDTO 类来覆盖GetHashCodeEquals 方法才能工作,但我找不到一些这样的例子。

有人可以告诉我从list2 中删除list1 的最佳方法吗?

再次感谢

【问题讨论】:

    标签: c# linq linq-to-entities


    【解决方案1】:

    您可能可以使用 except 方法来执行此操作。

    var newList = list2.Except(list1).ToList();
    

    如果你想替换 list2 那就这样做:

    list2 = list2.Except(list1).ToList();
    

    来自 MSDN:

    要比较自定义数据类型,请实现 IEquatable 泛型 接口并提供您自己的 GetHashCode 和 Equals 方法 类型。默认相等比较器 Default 用于比较 实现 IEquatable 的类型的值。

    【讨论】:

    • 谢谢,我最终相应地修改了我的课程,以便我可以使用除()...谢谢大家,我相信所有其他解决方案都一样好... :)
    【解决方案2】:
    var list1 = new List<string> { "A", "B", "C" };
    var list2 = new List<string> { "A", "C", "E", "B", "D", "G", "F" };
    list2.RemoveAll(list1.Contains);
    

    也可以。注意 list1.Contains 实际上是一个 lambda

    s => list1.Contains(s)
    

    -A.

    【讨论】:

    • 我不知道为什么,但 RemoveAll() 不适合我...
    • list.Contains 实际上不是 lambda。虽然它在这里的行为相同。
    • 我提到这一点是因为我认为 RemoveAll 采用谓词很重要,特别是因为 OP 的对象可能没有实现相等/比较。
    • RemoveAll 仅存在于 List 上。如果您使用的是 IList,那么您将无法使用它。
    • 如前所述,IList 不包含RemoveAll 方法
    【解决方案3】:

    哈希它绝对是一个好方法,@Jon Skeet 下面对类似问题的回答将为您提供解决方案。

    所以基本上语法是:

     var setToRemove = new HashSet<ItemDTO>(list1);
     list2.RemoveAll(x => setToRemove.Contains(x));
    

    Using LINQ to remove elements from a List<T>

    希望这会有所帮助。

    【讨论】:

    • 我不知道为什么,但 RemoveAll() 不适合我...
    • IList是List实现的接口。IList用于其他集合类。 List 类包含可能未在 IList 中定义的方法。因此,通过将原始列表对象分配给 IList,您将无法再访问 List 的任何唯一方法。除非您有使用 IList 的理由,否则我建议您使用 List。 MSDN:msdn.microsoft.com/en-us/library/6sh2ey19.aspx
    【解决方案4】:

    这意味着您需要告诉 .net 运行时如何确定一个类的两个实例是否相等(例如,它应该如何定义 ItemDTO 的一个实例是否等于 ItemDTO 的另一个实例)。

    为此,请覆盖 Equals

    public class ItemDTO
    {
        public override bool Equals(object obj)
        {
            var otherItem = obj as ItemDTO;
    
            if (otherItem == null)
            {
                // this will be because either 'obj' is null or it is not of type ItemDTO.
                return false;
            }
    
            return otherItem.SomeProperty == this.SomeProperty 
                   && otherItem.OtherProperty == this.OtherProperty;
        }
    }
    

    如果您不这样做,它只会删除列表中指向与另一个相同物理实例的任何引用。然后,您可以使用 except 或 RemoveAll 方法或您决定使用的任何其他方法。

    您还需要覆盖 GetHashcode,有关详细信息,请参阅下面的链接。

    Guidelines for Overloading Equals and GetHashcode

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-28
      • 2016-07-02
      • 2011-10-21
      相关资源
      最近更新 更多