I have a list of objects with a property that can be used to partition the objects into pairs. I know in advance that each object is part of a pair.
Here is an example to illustrate the situation:
Let's say my list is as follows:
List<Shoe> shoes = new List<Shoe>();
shoes.Add(new Shoe { Id = 19, Brand = "Nike", LeftOrRight = LeftOrRight.L });
shoes.Add(new Shoe { Id = 29, Brand = "Nike", LeftOrRight = LeftOrRight.R });
shoes.Add(new Shoe { Id = 11, Brand = "Nike", LeftOrRight = LeftOrRight.L });
shoes.Add(new Shoe { Id = 60, Brand = "Nike", LeftOrRight = LeftOrRight.R });
shoes.Add(new Shoe { Id = 65, Brand = "Asics", LeftOrRight = LeftOrRight.L });
shoes.Add(new Shoe { Id = 82, Brand = "Asics", LeftOrRight = LeftOrRight.R });
I would like to output these shoes as pairs, like so:
Pair: Id: 19, Brand: Nike, LeftOrRight: L Id: 29, Brand: Nike, LeftOrRight: R Pair: Id: 11, Brand: Nike, LeftOrRight: L Id: 60, Brand: Nike, LeftOrRight: R Pair: Id: 65, Brand: Asics, LeftOrRight: L Id: 82, Brand: Asics, LeftOrRight: R
Note that an individual shoe can only exist as part of a single pair.
I have tried the following code to group the shoes, but it is clearly missing the pairs:
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();
}
What statements can be used to group these items into pairs?
Pure functional LINQ, using SelectMany
and Zip
, yielding an IEnumerable
of Tuple
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
)
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With