Dites que j'ai ce qui suit:
class Widget1{
public int TypeID { get; set; }
public string Color { get; set; }
}
class Widget2
{
public int TypeID { get; set; }
public string Brand { get; set; }
}
private void test()
{
List<Widget1> widgets1 = new List<Widget1>();
List<Widget2> widgets2 = new List<Widget2>();
List<Widget1> widgets1_in_widgets2 = new List<Widget1>();
//some code here to populate widgets1 and widgets2
foreach (Widget1 w1 in widgets1)
{
foreach (Widget2 w2 in widgets2)
{
if (w1.TypeID == w2.TypeID)
{
widgets1_in_widgets2.Add(w1);
}
}
}
}
J'utilise deux boucles foreach pour comparer les listes par TypeID afin de remplir une troisième liste. Existe-t-il un autre moyen d’utiliser LINQ pour comparer ces deux listes via le TypeID? Peut-être en utilisant Interstect ou une autre fonction?
Ce que vous voulez ici est un Join
.
var widgets1_in_widgets2 = from first in widgest1
join second in widgets2
on first.TypeID equals second.TypeID
select first;
Intersect
peut être plus ou moins considéré comme un cas spécial de Join
où les deux séquences sont du même type, et peut donc être appliqué pour l'égalité au lieu d'avoir besoin d'une projection pour chaque type générer une clé pour comparer. Compte tenu de votre cas, Intersect
n'est pas une option.
Si un ID particulier est dupliqué dans votre deuxième ensemble et que vous ne voulez pas que l'élément soit dupliqué dans les résultats, vous pouvez utiliser un GroupJoin
au lieu d'un Join
:
var widgets1_in_widgets2 = from first in widgest1
join second in widgets2
on first.TypeID equals second.TypeID
into matches
where matches.Any()
select first;
Tu peux le faire
widgets2.Where(y=>widget1.Any(z=>z.TypeID==y.TypeID));
Join a l'inconvénient que vos résultats peuvent être dupliqués si widgets1 ou widgets2 contient plusieurs éléments avec le même TypeID (ce qui s'applique également à votre code d'origine, d'ailleurs).
Ce qui suit fera exactement ce que vous voulez: Renvoyer tous les éléments de widgets1 pour lesquels un élément avec un TypeID correspondant existe dans widgets2.
widgets1_in_widgets2 = (from w1 in widgets1
where widgets2.Any(w2 => w1.TypeID == w2.TypeID)
select w1).ToList()
J'aime cette solution car elle est simple à lire dans le code.
bool result = firstList.All(o => secondList.Any(w => w.Prop1 == o.Prop1 && w.Prop2 == o.Prop2));
Voir l'exemple complet dans le violon: exemple de comparaison au violon
Essayez d'utiliser la surcharge de "Où"
var isMatch = !widgets1.Where((w1, index) => w1.TypeId == widgets2[index].TypeId)).Any();