2009-11-04 63 views
2

的交叉比較,如果我有:如何做一個自定義的每個項目中的兩個集合

IEnumerable<CrewBase> crewBasesLeft; 
IEnumerable<CrewBase> crewBasesRight; 

做:

IEnumerable<CrewBase> intersect = crewBasesLeft 
.Intersect(crewBasesRight,CrewBaseComparer.OnId()); 

如何獲得:

CrewBase left; 
CrewBase right; 

來自:

intersect 

所以我可以遍歷所有的CrewBases在相交併撥打電話:

Action(left,right); 

我只想做這個CrewBases,根據我的CrewBaseComparer.OnId實現在這兩個列表相等:

IEqualityComparer<CrewBase> 

這是我目前實施:

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 other = crewBase; 
      ObjectDifference diff = crewBase.GetDifference(right.CrewBases.First(x => x.Equals(other, CrewBaseComparer.OnId()))); 
      if(diff.HasDifferences) 
      { 
       result.Add(diff); 
      } 
     } 

     return result; 
    } 
+0

可能有助於澄清CrewBaseComparer.OnID()正在引用...假定您正在使用.NET 4。0泛型IEnumerable,其中Intersect I的所有調用表單都可以在MSDN文檔中看到,需要將Intersect的第二個參數作爲對IEqualityComparer的引用? – BillW 2009-11-04 01:57:24

+0

CrewBaseBaseComparer.OnID()是僅在CrewBase.ID上進行比較的IEqualityComparer 。 這是爲了讓CrewBase.Equal()中所有具有相同ID但不是nesesary的CrewBase對象相等。 – 2009-11-04 08:10:00

回答

5

你必須定義一個實現的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 
} 

,然後調用相交的類的實例:

IEnumerable<CrewBase> intersect = crewBasesLeft.Intersect(crewBasesRight, new CustomComparer()); 

這不一定相交,永遠傳承來自「左」的元素和「右」作爲參數的元素的情況下「x」和「y」,但從您的問題來看,這個問題並不明確。

根據您的更新,它看起來像你需要做一個加入代替:

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); 
} 

在這種加盟,我們對待每一個元素作爲密鑰,並用您的現有自定義的IEqualityComparer比較實例。連接的結果選擇器返回一個匿名類型,其屬性「left」和「right」對應於左右集合中的元素。然後,您可以迭代結果來執行您的操作。

+0

我更新了問題。 「 – 2009-11-04 14:50:49

+0

我不明白你的說法: 」不一定這樣,Intersect將總是分別從「left」和從「right」傳遞一個元素作爲參數「x」和「y」,但是從你的問題是否重要。「 Intersect方法不會返回與Join相同的左對象嗎? – 2009-12-27 13:22:47

+0

一組交集包含不同的元素。來自MSDN:「相交首先枚舉[第一組],收集該序列的所有不同元素。」 IEqualityComparer將用於比較第一個集合中的元素以建立一個不同的集合,然後用於比較不同的第一個集合和第二個集合之間的元素。您不能假定IEqualityComparer Equals方法的參數x和y分別來自左側和右側集。例如,他們可能都來自左邊的集合。 – 2009-12-30 19:18:37

1

我想你可能對交叉點有一點誤解。如果您採用兩個列表的相交點,則看起來像您正在做的那樣,結果將會是一個列表,其中包含列表中的所有的所有元素。

因此一旦你做到

IEnumerable<CrewBase> crewBasesLeft; 
IEnumerable<CrewBase> crewBasesRight; 
IEnumerable<CrewBase> intersect = crewBasesLeft.Intersect(crewBasesRight,CrewBaseComparer.OnId()); 

了IEnumerable在相交併不需要向左或向右。

但是,如果你想要做的是讓你自定義的IEqualityComparer左右,那麼你需要的是一個看起來像這樣的對象:

class CrewBaseIdComparer : IEqualityComparer<CrewBase> 
{ 
    public bool Equals(CrewBase left, CrewBase right) 
    { 
     // your logic 
    } 

    public int GetHashCode(CrewBase item) 
    { 
     // your logic 
    } 
} 
相關問題