我有物品清单。
项目的指定方式如下:
public class Item
{
public List<decimal> Values { get; set; }
public string GroupingKey { get; set; }
public List<int> Cycle { get; set; }
}
我想通过对键进行分组,对项实例列表进行分组,并按列表中的索引对值进行求和,然后添加到一个列表中。每个组的周期列表相同,因此只需将其添加到新组中即可。
例如,以下列表:
List<Items>
{
Values { 2, 3, 5 },
GroupingKey = "P23",
Cycle { 1, 2, 3, 4 }
},
{
Values { 10, 20, 30 },
GroupingKey = "P23",
Cycle { 1, 2, 3, 4 }
},
{
Values { 10, 20, 30 },
GroupingKey = "P24",
Cycle { 1, 2, 3, 4 }
}
最终看起来像这样:
List<Items>
{
Values { 12, 23, 35},
GroupingKey = "P23",
Cycle { 1, 2, 3, 4}
},
{
Values { 10, 20, 30},
GroupingKey = "P24",
Cycle { 1, 2, 3, 4}
}
具有相同键的Item实例可以更多,而不仅仅是两个。 关于如何使用LINQ解决此问题的任何想法?
谢谢。
答案 0 :(得分:1)
您可以使用一堆GroupBy
和Select
来实现:
var result = list.GroupBy(i => i.GroupingKey).ToList().Select(group => new Item
{
Values = group.SelectMany(item => item.Values
.Select((value, index) => new {value, index}))
.GroupBy(item => item.index)
.Select(a => a.Sum(e => e.value)).ToList(),
GroupingKey = group.Select(i => i.GroupingKey).FirstOrDefault(),
Cycle = group.Select(i => i.Cycle).FirstOrDefault()
});
答案 1 :(得分:-1)
您需要的是Enumerable.Zip
方法,该方法可跨多个序列工作。不幸的是,LINQ没有提供这种功能,因此我们必须投影索引并手动求和元素。
var merged = items
.GroupBy(x => x.GroupingKey)
.Select(grp => new Item
{
Values = Enumerable
.Range(0, grp.Max(x => x.Values.Count))
.Select(i => grp.Sum(x => x.Values.Count > i ? x.Values[i] : 0))
.ToList(),
GroupingKey = grp.Key,
Cycle = grp.First().Cycle // can add check that others are identical
})
.ToList();