如何基于属性获得两个类的交集

asd*_*hak 2 c# linq aggregate intersection

我有这门课

public class FlightSegment{
     public string ClassName { get;set;}
}
Run Code Online (Sandbox Code Playgroud)

而且我希望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

}
Run Code Online (Sandbox Code Playgroud)

我试过这样的事情:

    var intersection = listOfLists.Aggregate((previousList, nextList) =>   
      previousList.Select(e=>e.ClassName).Intersect(nextList.Select(e=>e.ClassName)).ToList());
Run Code Online (Sandbox Code Playgroud)

但是给出错误:

Cannot convert expression type System.Collection.Generic.List<string> to return type System.Collection.Generic.List<FlightSegment>
Run Code Online (Sandbox Code Playgroud)

Art*_*aca 5

您可以使用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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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());
Run Code Online (Sandbox Code Playgroud)

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

使用这个想法和Aggregate,您可以获得基于属性的一组列表的交集:

var intersection = listOfLists.Aggregate((previousList, nextList) => previousList.Intersect(nextList, new FlightComparer() ).ToList()); 
Run Code Online (Sandbox Code Playgroud)