How to do a custom compare for every item in a intersect of two collections
If I have:
IEnumerable<CrewBase> crewBasesLeft;
IEnumerable<CrewBase> crewBasesRight;
and do:
IEnumerable<CrewBase> intersect = crewBasesLeft
.Intersect( crewBasesRight,CrewBaseComparer.OnId() );
How do I get:
CrewBase left;
CrewBase right;
from the:
intersect
so I can loop over all the CrewBases in the Intersect and make a call:
Action(left,right);
I only want to do this on CrewBases that are equal in both list according to my CrewBaseComparer.OnId that implements:
IEqualityComparer<CrewBase>
This is my current implementation:
IEnumerable<ObjectDifference> GetCrewBaseDifferences2( TrafficPlan left, TrafficPlan right )
{
var result = new List<ObjectDifference>();
IEnumerable<CrewBase> intersect = left.CrewBases.Intersect( right.CrewBases,CrewBaseComparer.OnId() );
foreach( CrewBase crewBase in intersect )
{
CrewBase othe开发者_如何学编程r = crewBase;
ObjectDifference diff = crewBase.GetDifference( right.CrewBases.First(x => x.Equals(other, CrewBaseComparer.OnId())) );
if( diff.HasDifferences )
{
result.Add( diff );
}
}
return result;
}
You'd have to define a class that implements IEqualityComparer:
class CustomComparer : IEqualityComparer<CrewBase>
{
#region IEqualityComparer<CrewBase> Members
public bool Equals(CrewBase x, CrewBase y)
{
return CustomCompare(x, y);
}
public int GetHashCode(CrewBase obj)
{
//a hash code based on the specific comparison
}
#endregion
}
and then call Intersect with an instance of your class:
IEnumerable<CrewBase> intersect = crewBasesLeft.Intersect(crewBasesRight, new CustomComparer());
It's not necessarily the case that Intersect will always pass an element from "left" and an element from "right" as parameters "x" and "y" respectively, but it's not clear from your question if that matters.
Based on your update, it looks like you need to do a Join instead:
IEnumerable<CrewBase> crewBasesLeft;
IEnumerable<CrewBase> crewBasesRight;
var Join = crewBasesLeft.Join(crewBasesRight, left => left, right => right, (left, right) => new { left, right }, CrewBaseComparer.OnId());
foreach (var i in Join)
{
Action(i.left, i.right);
}
In this join, we treat each element as the key and use your existing custom IEqualityComparer to compare the instances. The result selector for the join returns an anonymous type with the properties "left" and "right" corresponding to elements from the left and right collections. Then, you may iterate over the result to perform your action.
I think you may have a bit of a misconception with an intersect. If you take the intersect of two lists, as it looks like you're doing, the result will be a single list that contains all of the elements that are in both of the lists.
Thus once you've done
IEnumerable<CrewBase> crewBasesLeft;
IEnumerable<CrewBase> crewBasesRight;
IEnumerable<CrewBase> intersect = crewBasesLeft.Intersect( crewBasesRight,CrewBaseComparer.OnId() );
The IEnumerable in intersect doesn't need left or right.
However, if what you're trying to do is get the left and right in your custom IEqualityComparer, then what you want is an object that looks something like this:
class CrewBaseIdComparer : IEqualityComparer<CrewBase>
{
public bool Equals(CrewBase left, CrewBase right)
{
// your logic
}
public int GetHashCode(CrewBase item)
{
// your logic
}
}
精彩评论