Linq-根据属性将列表分组
收藏

我有一个对象列表,其中有一个属性,可用于将对象分成对。我事先知道每个物体都是一对的一部分。
下面是一个例子来说明这种情况:
我有一张单双鞋的单子,我想把它们分成几双。
我的清单如下:

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

我想把这双鞋成对输出,比如:
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();
}

哪些语句可用于将这些项成对分组?


最佳答案:

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

注意:ZIP只能尽可能地配对。如果你有额外的权利或左,他们不会得到报告。

    公众号
    关注公众号订阅更多技术干货!