Linq - 根据属性将列表分组成对

Rya*_*ohn 6 c# 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 });
Run Code Online (Sandbox Code Playgroud)

我想把这双鞋作为成对输出,如下:

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

请注意,单个鞋只能作为单个鞋的一部分存在.

我已经尝试了以下代码来分组鞋子,但显然缺少对:

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();
}
Run Code Online (Sandbox Code Playgroud)

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

Tho*_*ith 8

纯功能LINQ,使用SelectManyZip,得到一个IEnumerableTupleS:

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
        )
    );
Run Code Online (Sandbox Code Playgroud)


Aus*_*nen 3

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();
}
Run Code Online (Sandbox Code Playgroud)

注意:Zip 只会尽可能地配对。如果您有额外的权利或左权,则不会被报告。