LoginSignup
2
6

More than 5 years have passed since last update.

自作クラスのリストを複数列でGroup byして集計する方法

Posted at

例として、衣類を管理するアパレルクラスなるものを用意しました。

販売店、アイテム名、サイズ、価格、在庫数を持っているクラスです。
まぁ、わかりやすくするために項目は少なめです(笑)

アパレルクラス

// アパレルクラス
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だけ実装しておけば便利かも。

2
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
6