删除一个IList中的项目<>来自另一个IList<>

时间:2012-02-15 22:54:03

标签: c# linq linq-to-entities

很抱歉发布这些基本问题,我是LINQ的新手,我正在努力找出最好的方法来完成每个IList的循环。

我有2 ILists<>个自定义dto对象。我想从列表中删除另一个中的所有匹配项。

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

我需要从list1中删除list2中的所有项目。我一直在查看Except()方法,但显然我需要我的ItemsDTO类覆盖GetHashCodeEquals方法才能使用,但我找不到这方面的例子。

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

再次感谢

4 个答案:

答案 0 :(得分:9)

您可以使用Except方法执行此操作。

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

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

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

来自MSDN:

  

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

答案 1 :(得分:1)

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

基本上语法是:

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

Using LINQ to remove elements from a List<T>

希望这会有所帮助。

答案 2 :(得分:1)

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。

答案 3 :(得分:0)

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

要执行此操作,请覆盖等于

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