【问题标题】:How to get intersection of two classes based on property如何根据属性获取两个类的交集
【发布时间】:2016-04-25 19:44:06
【问题描述】:

我有这门课

public class FlightSegment{
     public string ClassName { get;set;}
}

我想得到FlightSegments 和普通的ClassName

void Main()
{
    var list1 = new List<FlightSegment>() { 
        new FlightSegment{ ClassName = "A"},
        new FlightSegment { ClassName = "B"}
    };      
    var list2 = new List<FlightSegment>() { 
        new FlightSegment{ ClassName = "B"},
        new FlightSegment { ClassName = "C"}
    }; 

    var listOfLists = new List<List<FlightSegment>>() { list1, list2 };     
    var intersection = listOfLists.Aggregate((previousList, nextList) => previousList.Intersect(nextList).ToList());        
    Console.WriteLine(intersection); //Gives me empty result

}

我尝试过这样的事情:

    var intersection = listOfLists.Aggregate((previousList, nextList) =>   
      previousList.Select(e=>e.ClassName).Intersect(nextList.Select(e=>e.ClassName)).ToList());

但是报错:

Cannot convert expression type System.Collection.Generic.List<string> to return type System.Collection.Generic.List<FlightSegment>

【问题讨论】:

    标签: c# linq aggregate intersection


    【解决方案1】:

    您可以使用Intersect 方法传递IEqualityComparer 来根据ClassName 属性进行比较:

    class FlightComparer : EqualityComparer<FlightSegment>
    {
        public override bool Equals(FlightSegment x, FlightSegment y)
        {
            return x.ClassName == y.ClassName;
        }
    
        public override int GetHashCode(FlightSegment obj)
        {
            return obj.ClassName.GetHashCode();
        }
    }
    

    然后,使用此比较器进行交集:

    var list1 = new List<FlightSegment>() { 
        new FlightSegment{ ClassName = "A"},
        new FlightSegment { ClassName = "B"}
    };      
    var list2 = new List<FlightSegment>() { 
        new FlightSegment{ ClassName = "B"},
        new FlightSegment { ClassName = "C"}
    }; 
    var result = list1.Intersect(list2, new FlightComparer());
    

    这将返回一个仅包含一个元素 FlightSegment { ClassName = "B" } 的集合。

    利用这个思路和Aggregate,可以根据一个属性得到一组列表的交集:

    var intersection = listOfLists.Aggregate((previousList, nextList) => previousList.Intersect(nextList, new FlightComparer() ).ToList()); 
    

    【讨论】:

    • 不错的答案。请注意文档中的指导,“我们建议您从EqualityComparer&lt;T&gt; 类派生而不是实现IEqualityComparer&lt;T&gt; 接口,因为EqualityComparer&lt;T&gt; 类使用IEquatable&lt;T&gt;.Equals 方法而不是Object.Equals 方法测试相等性。 "
    • 很高兴了解继承 EqualityComparer 而不是实现 IEqualityComparer
    猜你喜欢
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 2019-08-12
    • 2019-12-07
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    相关资源
    最近更新 更多