4

次の例のような形状のデータに対して 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();

誰でも助けることができますか?

[編集: メソッドまたはクエリ構文のうち、プロセスを視覚化するのが簡単な方を使用できます]

4

3 に答える 3

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()
于 2013-01-13T17:30:31.137 に答える
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 
    }
}
于 2013-01-13T17:39:43.863 に答える
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)
            })
    });
于 2013-01-13T17:50:40.367 に答える