Reputation: 27
I have List of items.
Item is specified like:
public class Item
{
public List<decimal> Values { get; set; }
public string GroupingKey { get; set; }
public List<int> Cycle { get; set; }
}
I want to group a List of Item instances by grouping key and sum Values by index in list and add into one list. Cycle list is same for each group so just add this into new group
For example, the following List:
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 }
}
would end up looking like:
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 instances with same key can be more and not only two. Any ideas on how to solve this using LINQ?
Thank you.
Upvotes: 1
Views: 1109
Reputation: 86
You can achieve that by using a bunch of GroupBy
and Select
's:
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()
});
Upvotes: 2
Reputation: 54887
What you need is an Enumerable.Zip
method that works across multiple sequences. Unfortunately, LINQ doesn't provide such, so we have to project the indexes and sum the elements manually.
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();
Upvotes: -1