自作クラスのリストを複数列でGroup byして集計する方法
例として、衣類を管理するアパレルクラスなるものを用意しました。
販売店、アイテム名、サイズ、価格、在庫数を持っているクラスです。
まぁ、わかりやすくするために項目は少なめです(笑)
アパレルクラス
// アパレルクラス
private class APPAREL
{
public APPAREL()
{
}
public APPAREL(string shop, string itemName, Sizes size, int stock, int price)
{
this.Shop = shop;
this.ItemName = itemName;
this.Size = size;
this.StockCount = stock;
this.Price = price;
}
// 店舗名
public string Shop { get; set; }
// アイテム名
public string ItemName { get; set; }
// サイズ
public Sizes Size { get; set; }
// 在庫数
public int StockCount { get; set; }
// 販売価格
public int Price { get; set; }
// Size
public enum Sizes
{
XXS = 0,
XS,
S,
M,
L,
XL,
XXL
}
/// <summary>
/// GroupByメソッド
/// 全店舗のアイテム・サイズ毎の在庫数、販売価格を取得するメソッド
/// </summary>
/// <param name="list">
/// Group byするリスト
/// </param>
/// <returns>
/// Group byしたリスト
/// </returns>
public static List<APPAREL> GroupBy(List<APPAREL> list)
{
List<APPAREL> gbyList = (from a in list
orderby a.ItemName,a.Size
group a by new { a.ItemName, a.Size } into g
select new APPAREL
{
Shop = string.Empty, // ショップ名はgroup対象外なのでEmpty
ItemName = g.Max(s => s.ItemName), // 文字列でもMaxでOK
Size = g.Max(s => s.Size), // 列挙体でもMaxでOK
StockCount = g.Sum(s => s.StockCount),
Price = g.Sum(s => s.Price)
}).ToList();
return gbyList;
}
}
このクラスのGroupByメソッドにリストを引数として渡すと
アイテム名とサイズでGroupByを行いリストで返却するように作ってあります。
「group a by new { a.ItemName, a.Size }」の「 a.ItemName, a.Size 」の箇所に
グループ化したい項目を記述していく感じになります。
実際にサンプルデータを作成してメソッドを実行した場合の処理と
返却結果をJsonに変換した場合の結果が下記です。
static void Main(string[] args)
{
List<APPAREL> appList = new List<APPAREL>();
APPAREL re = new APPAREL();
//適当にテストデータを追加します
appList.Add(new APPAREL("周防大島", "シャツ", APPAREL.Sizes.S, 2, 4500));
appList.Add(new APPAREL("橘", "シャツ", APPAREL.Sizes.S, 3, 4500));
appList.Add(new APPAREL("久賀", "シャツ", APPAREL.Sizes.M, 4, 5000));
appList.Add(new APPAREL("長崎", "シャツ", APPAREL.Sizes.S, 5, 4500));
appList.Add(new APPAREL("下田", "シャツ", APPAREL.Sizes.L, 6, 3820));
appList.Add(new APPAREL("神浦", "シャツ", APPAREL.Sizes.S, 7, 2980));
appList.Add(new APPAREL("周防大島", "ジャケット", APPAREL.Sizes.M, 2, 14500));
appList.Add(new APPAREL("橘", "ジャケット", APPAREL.Sizes.XXL, 3, 10500));
appList.Add(new APPAREL("久賀", "ジャケット", APPAREL.Sizes.XXS, 4, 10800));
appList.Add(new APPAREL("長崎", "ジャケット", APPAREL.Sizes.S, 5, 4500));
appList.Add(new APPAREL("下田", "ジャケット", APPAREL.Sizes.XXL, 6, 14500));
appList.Add(new APPAREL("神浦", "ジャケット", APPAREL.Sizes.S, 7, 12000));
// グループ化!
List<APPAREL> liAPPAREL = APPAREL.GroupBy(appList);
// 余談「JsonConvert.SerializeObject」の第二引数に「Formatting.Indented」を指定すると
// Json文字列が整形される
string json = JsonConvert.SerializeObject(liAPPAREL, Formatting.Indented);
Console.WriteLine(json);
/* 出力結果 (わかりやすいようにJsonにシリアライズしています)
[
{
"Shop": "",
"ItemName": "ジャケット",
"Size": 0,
"StockCount": 4,
"Price": 10800
},
{
"Shop": "",
"ItemName": "ジャケット",
"Size": 2,
"StockCount": 12,
"Price": 16500
},
{
"Shop": "",
"ItemName": "ジャケット",
"Size": 3,
"StockCount": 2,
"Price": 14500
},
{
"Shop": "",
"ItemName": "ジャケット",
"Size": 6,
"StockCount": 9,
"Price": 25000
},
{
"Shop": "",
"ItemName": "シャツ",
"Size": 2,
"StockCount": 17,
"Price": 16480
},
{
"Shop": "",
"ItemName": "シャツ",
"Size": 3,
"StockCount": 4,
"Price": 5000
},
{
"Shop": "",
"ItemName": "シャツ",
"Size": 4,
"StockCount": 6,
"Price": 3820
}
]
*/
}
使いドコロはまぁそれなりに限られますが、よく使うGroupByだけ実装しておけば便利かも。
Author And Source
この問題について(自作クラスのリストを複数列でGroup byして集計する方法), 我々は、より多くの情報をここで見つけました https://qiita.com/harukichi/items/7908c59a5d2a17d58c31著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .