我正在努力使用C#/ LINQ进行双重分组,其形状类似于以下示例。我从一个来自数据层的TickItems列表开始,我现在已经形成了这样的形状:
TickItem {
ItemName: string;
QtyNeeded: int;
QtyFulfilled: int;
Category: string;
}
List<TickItem> items = new List<TickItem>();
items.Add("apple", 1, 0, "food");
items.Add("orange", 1, 1, "food");
items.Add("orange", 1, 0, "food");
items.Add("bicycle", 1, 1, "vehicle");
items.Add("apple", 1, 1, "food");
items.Add("apple", 1, 0, "food");
items.Add("car", 1, 1, "vehicle");
items.Add("truck", 1, 0, "vehicle");
items.Add("banana", 1, 0, "food");
我需要按类别对此数据进行分组,并在最终结果中使用每个数字列的总和。最后,它的形状应该是这样的:
{ "food": { "apple" : 3, 1 },
{ "banana" : 1, 0 },
{ "orange" : 2, 1 } },
{ "vehicle": { "bicycle": 1, 1 },
{ "car" : 1, 1 },
{ "truck" : 1, 0} }
我已经能够单独执行每个分组(按ItemName分组,按类别分组),但我无法在单个LINQ语句中执行这两个分组。到目前为止我的代码:
var groupListItemName = things.GroupBy(tiλ => tiλ.ItemName).ToList();
var groupListCategory = things.GroupBy(tiλ => tiλ.Category).ToList();
有人可以帮忙吗?
[编辑:我可以使用任何方法或查询语法,以更容易使过程可视化的方式]
答案 0 :(得分:2)
请看一下这篇文章。
http://sohailnedian.blogspot.com/2012/12/linq-groupby-with-aggregate-functions.html
可以通过new关键字进行多次分组。
empList.GroupBy(_ => new { _.DeptId, _.Position })
.Select(_ => new
{
MaximumSalary = _.Max(deptPositionGroup => deptPositionGroup.Salary),
DepartmentId = _.Key.DeptId,
Position = _.Key.Position
}).ToList()
答案 1 :(得分:1)
var query = from i in items
group i by i.Category into categoryGroup
select new
{
Category = categoryGroup.Key,
Items = categoryGroup.GroupBy(g => g.ItemName)
.Select(g => new
{
ItemName = g.Key,
QtyNeeded = g.Sum(x => x.QtyNeeded),
QtyFulfilled = g.Sum(x => x.QtyFulfilled)
}).ToList()
};
此查询将返回表示按类别分组的项目的匿名对象序列。每个类别对象都有匿名对象列表,其中包含每个项目名称的总计。
foreach(var group in query)
{
// group.Category
foreach(var item in group.Items)
{
// item.ItemName
// item.QtyNeeded
// item.QtyFulfilled
}
}
答案 2 :(得分:0)
GroupBy
有一个重载,允许您指定结果转换,例如:
var result = items.GroupBy(i => i.Category,
(category, categoryElements) => new
{
Category = category,
Elements = categoryElements.GroupBy(i => i.ItemName,
(item, itemElements) => new
{
Item = item,
QtyNeeded = itemElements.Sum(i => i.QtyNeeded),
QtyFulfilled = itemElements.Sum(i => i.QtyFulfilled)
})
});