2009-11-04 7 views
2

Si j'ai:Comment faire une coutume de comparer pour chaque élément dans une Intersection de deux collections

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

et à faire:

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

Comment puis-je obtenir:

CrewBase left; 
CrewBase right; 

du:

intersect 

donc je ne peux boucler sur tous les CrewBases dans l'Intersect et faire un appel:

Action(left,right); 

Je veux seulement faire sur CrewBases qui sont égaux dans les deux liste selon mon CrewBaseComparer.OnId qui implémente:

IEqualityComparer<CrewBase> 

Voici mon implémentation actuelle:

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

pourrait être utile de clarifier CrewBaseComparer.OnID() fait référence ... en supposant que vous utilisez .NET 4.0 générique IEnumerable, dans lequel tout le formulaire d'appel pour Intersect je peux voir dans les documents MSDN nécessite le deuxième argument à Intersect pour être une référence à un IEqualityComparer? – BillW

+0

Le CrewBaseBaseComparer.OnID() est IEqualityComparer qui ne compare que sur CrewBase.ID. Ceci permet d'obtenir que tous les objets CrewBase ayant le même ID mais pas le nesesary soient égaux sur CrewBase.Equal(). –

Répondre

5

Il faudrait définir une classe qui implémente 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 
} 

puis appelez Intersection avec une instance de votre classe:

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

Ce n'est pas nécessairement le cas que Intersection passera toujours un élément de « gauche » et un élément de « droit » en tant que paramètres "x" et "y" respectivement, mais ce n'est pas clair d'après votre question si cela compte.

Sur la base de votre mise à jour, il semble que vous devez faire une place inscription:

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

Dans cette jointure, nous traitons chaque élément comme la clé et utiliser votre IEqualityComparer personnalisée existante pour comparer les cas. Le sélecteur de résultat pour la jointure renvoie un type anonyme avec les propriétés "left" et "right" correspondant aux éléments des collections gauche et droite. Ensuite, vous pouvez itérer sur le résultat pour effectuer votre action.

+0

J'ai mis à jour la question. –

+0

Je ne comprends pas votre déclaration: "Intersect ne transmettra pas toujours un élément de" left "et un élément de" right "comme paramètres" x "et" y "respectivement, mais cela n'est pas clair votre question si cela compte. " La méthode Intersection ne retournerait-elle pas les mêmes objets que la jointure? –

+0

Une intersection définie contient des éléments distincts. De MSDN: "Intersect énumère d'abord [le premier ensemble], en rassemblant tous les éléments distincts de cette séquence." Le IEqualityComparer sera utilisé pour comparer les éléments du premier ensemble afin d'établir un ensemble distinct, puis utilisé pour comparer les éléments entre les premier et deuxième ensembles distincts. Vous ne pouvez pas supposer que les paramètres x et y de la méthode IEqualityComparer Equals proviennent respectivement des ensembles gauche et droit. Par exemple, ils peuvent tous deux provenir de l'ensemble de gauche. –

1

Je pense que vous pouvez avoir un peu d'une idée fausse avec un croisement. Si vous prenez l'intersection de deux listes, comme il semble que vous faites, le résultat sera une seule liste qui contient tous les éléments qui sont les deux des listes.

Ainsi, une fois que vous avez fait

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

Le IEnumerable en Intersection n'a pas besoin de gauche ou de droite.

Cependant, si ce que vous essayez de faire est d'obtenir la gauche et à droite dans votre commande IEqualityComparer, alors ce que vous voulez est un objet qui ressemble à ceci:

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

    public int GetHashCode(CrewBase item) 
    { 
     // your logic 
    } 
} 
Questions connexes