我有一个对象列表,其中包含可用于将对象分成对的属性。我事先知道每个物体都是一对的一部分。
以下是一个说明情况的例子:
<小时/> 我有一个单独的鞋子列表,我想成对分组。
假设我的清单如下:
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
请注意,单个鞋只能作为单个鞋的一部分存在。
我已尝试使用以下代码对鞋子进行分组,但显然缺少对:
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();
}
可以使用哪些语句将这些项分组成对?
答案 0 :(得分:8)
纯函数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
)
);
答案 1 :(得分: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();
}
注意:Zip只会尽可能多地配对。如果你有额外的权利或左派,他们就不会被报道。
答案 2 :(得分:2)
一种方法:
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));
这可能是我最初的想法(很好implemented by Thom Smith)的一个改进,因为对于每个品牌的鞋子,它只通过迭代一次只能将它们分成左右两双鞋子。 Gut的感觉说,如果有很多品牌的鞋子应该会更快。
它的作用是按品牌分组鞋子,然后按左/右分组。然后,它会随机匹配每个品牌的左鞋和相同的鞋子,依次对所有品牌进行匹配。