我有一个具有属性的对象列表,可用于将对象分成对.我事先知道每个物体都是一对的一部分.
这是一个说明情况的例子:
假设我的清单如下:
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)
可以使用哪些语句将这些项分组成对?
纯功能LINQ,使用SelectMany
和Zip
,得到一个IEnumerable
的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
)
);
Run Code Online (Sandbox Code Playgroud)
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 只会尽可能地配对。如果您有额外的权利或左权,则不会被报告。