J'ai une liste d'objets avec une propriété pouvant être utilisée pour partitionner les objets en paires. Je sais à l'avance que chaque objet fait partie d'une paire.
Voici un exemple pour illustrer la situation: p>
p>
J'ai une liste de chaussures individuelles que j'aimerais regrouper en paires. P>
Disons que ma liste est la suivante: P>
var pairsByBrand = shoes.GroupBy(s => s.Brand);
foreach (var group in pairsByBrand)
{
Console.WriteLine("Pair:");
foreach (var shoe in group)
{
Console.WriteLine(shoe);
}
Console.WriteLine();
}
3 Réponses :
var shoesByBrand = shoes.GroupBy(s => s.Brand);
foreach (var byBrand in shoesByBrand)
{
var lefts = byBrand.Where(s => s.LeftOrRight == LeftOrRight.L);
var rights = byBrand.Where(s => s.LeftOrRight == LeftOrRight.R);
var pairs = lefts.Zip(rights,(l, r) => new {Left = l, Right = r});
foreach(var p in pairs)
{
Console.WriteLine("Pair: {{{0}, {1}}}", p.Left.Id, p.Right.Id);
}
Console.WriteLine();
}
Note: Zip will only pair up as much as it can. If you have extra rights or lefts they won't get reported.
+1 J'ai besoin de lire sur groupeby et zip contre, il a l'air fort :) BTW, avez-vous voulu dire Console.ReDkey (); À la fin à la fin?
Je
@Aquinas: Si vous commencez à répertorier toutes les paires possibles i>, la sortie explose avec relativement peu de chaussures. Il y avait une certaine ambiguïté dans la question mais votre réponse et votre mienne devraient le couvrir.
Alors que la réponse de Thom Smith était plus succincte, j'ai fini par utiliser celui-ci parce que le code était plus clair.
Pure Linq fonctionnel, à l'aide de SelectMany code> et zip code>, cédant un ienumerable code> de tuple code> S: IEnumerable<Tuple<Shoe, Shoe>> pairs = shoes
.GroupBy(shoe => shoe.Brand)
.SelectMany(brand=>
Enumerable.Zip(
brand.Where(shoe=>shoe.LeftOrRight == LeftOrRight.L),
brand.Where(shoe=>shoe.LeftOrRight == LeftOrRight.R),
Tuple.Create
)
);
Belle solution, mais encore une fois, ne sont pas des paires (avec gauche et droite) qui sont la même marque capable d'être regroupées? Avec cette solution, vous obtiendrez différentes appariements en fonction de la commande que les chaussures apparaissent dans la liste. Donc, si j'ajoute des chaussures 11, puis 60, ils formeront une paire, mais si j'ajoute 11 et 29 i> d'abord, ils formeraient une paire. Est-ce ce qui est attendu? Nous avons besoin de l'OP pour peser.
@aquinas: L'OP a déjà clarifié que deux chaussures de gauche de la même marque sont identiques aux fins de la présente discussion.
Mon interprétation était que chaque chaussure doit être présente exactement une fois dans la sortie et que l'ordre n'était pas pertinent tant que chaque paire était valide. L'OP peut avoir été un peu vague sur ce point.
Un moyen de le faire:
var pairs = shoes.GroupBy(s => s.Brand)
.Select(g => g.GroupBy(s => s.LeftOrRight));
.SelectMany(Enumerable.Zip(g => g.First(), g => g.Last(),Tuple.Create));
Qu'est-ce qui empêche la paire {19,60}?
@AustinSalonen que la paire serait acceptable aussi. La seule restriction est que les paires doivent être de la même marque, à gauche et à une chaussure droite.
@Ryan Kohn Vous avez besoin d'une autre propriété, par exemple le produitName et chaque L et R, qui devrait être une paire, doit avoir le même nom de produit. Ensuite, groupe par produit non par marque, car par marque, vous avez 4 articles pour le groupe Nike et 2 pour le groupe Asics