简体   繁体   English

如果我不能直接修改类,如何使用元素类型的字段值从另一个列表中删除列表?

[英]How can I remove a list from another list using a field value of the element's type if i can't modify the class directly?

Suppose I have a List<Product> named big of some object Product which has 2 fields, ID and Name . 假设我有一个List<Product>bigList<Product> ,该对象的某些对象Product具有2个字段IDName The list is fully populated, meaning that each element has both fields not null , although they can be. 该列表已完全填充,这意味着每个元素都具有两个不为null字段,尽管可以。

I have another List<Product> , smaller than the first, named small , but this time the field Name is null for some elements, while ID is always present. 我还有另一个List<Product> ,它小于第一个,名为small ,但是这次某些元素的字段Namenull ,而ID始终存在。

I want to remove small from big where ID is the same. 我想从ID相同的big中删除small

Example: 例:

List<Product> big = { {1,A},{2,B},{3,C},{4,D} };
List<Product> small = { {1,null},{3,C} };
List<Product> result = { {2,B},{4,D}};

I can't modify the Product object, ie I can't implement IEquatable<Product> , and such interface isn't implemented, meaning that big.Except(small) or big.RemoveAll(small) or big.Contains(anElementOfSmall) won't work (for the sake of the question, I've tried them). 我无法修改Product对象,即无法实现IEquatable<Product> ,并且此类接口未实现,这意味着big.Except(small)big.RemoveAll(small)big.Contains(anElementOfSmall)将无法正常工作(出于疑问,我已经尝试过了)。

I want to avoid the double loop with iterator removal or similar, I'm searching for built-in functions with specific predicates. 我想避免使用删除迭代器或类似方法的双循环,我在搜索带有特定谓词的内置函数。

Using a simple predicate you can easily achieve it: 使用简单的谓词,您可以轻松实现:

big.Where(p => !small.Any(o => o.id == p.id)).ToList();

which translates in: select from big where the element ( p ) doesn't suffice the case where an element o in small has the same ID . 转换为:从big元素中选择( p )不能满足其中small元素o具有相同ID

Implement an IEqualityComparer for your Product that compares two Product based on ID . 为您的产品实现IEqualityComparer ,以根据ID比较两个Product Then just use Except and pass the comparer: 然后只需使用Except并通过比较器即可:

var result = big.Except(small, new ProductComparer()).ToList();

You need to tell Except how to compare instances of Product . 您需要告诉Except如何比较Product实例。

public class ProductEqualityComparer : IEqualityComparer<Product>
{
    public bool Equals(Product x, Product y)
    {
        //they're both the same instance or they're both null
        if(ReferanceEquals(x, y))
            return true;

        //only one of them is null
        if(x == null || y == null)
            return false;

        return x.Id == y.Id;
    }

    public int GetHashCode(Product prod)
    {
        return prod == null? 0 : prod.Id.GetHashCode();
    }
}


big.Except(small, new ProductEqualityComparer())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM