C#:Listの重複要素をDictionaryのKeyにグルーピングしたい時

記事公開日:
最終更新日:

This post is also available in: English-US (英語)

本記事はC#でList型内の重複要素を、Dictionary型のKeyにグルーピングして値を取り出したい時の方法について書いています。
「何やらLinqのGroupbyを使ったら綺麗なコードが書けるらしいけど、とりあえずコンソールに重複要素をグルーピングした値を出したいんだ!」という方に最適な記事かと思います。

List内の重複要素をDictionaryのKeyにグルーピング

VisualStudioで生成した、C#のコンソールアプリケーションを例に、重複要素をLinqを使ってグルーピングするサンプルコードです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SampleConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            //Result型のリスト作成、重複要素あり
            List<Result> data = new List<Result>();
            //データの追加
            data.Add(new Result(0, "田中", "大阪"));
            data.Add(new Result(1, "鈴木", "大阪"));
            data.Add(new Result(2, "田中", "名古屋"));
            data.Add(new Result(3, "鈴木", "東京"));
            data.Add(new Result(4, "鈴木", "大阪"));
            //辞書型の作成と同時にLinqでaddressをグルーピング化
            Dictionary<string, List<Result>> dict = data
            .ToLookup(Result => Result.address)
            .ToDictionary(
            g => g.Key,
            g => g.ToList()
            );
            //dictを格納するための配列を作成
            string[] values = new string[dict.Count];
            //dictのKeyをコピー
            dict.Keys.CopyTo(values, 0);
            //コピーしたKeyをソート
            Array.Sort(values);
            //valuesの中身を取り出す
            for (int i = 0; i < dict.Count; i++)
            {
                Console.WriteLine("---values[i]---");
                Console.WriteLine(values[i]);
                Console.WriteLine("---dict[\"大阪\"][i].name---");
                Console.WriteLine(dict["大阪"][i].name);
            }
            Console.ReadKey();
        }

        // List<Result> dataのクラス
        public class Result
        {
            public int id;
            public string name;
            public string address;
            public Result(int _id, string _name, string _address)
            {
                id = _id; name = _name; address = _address;
            }
        }

    }
}

Linqを使ってグルーピングしたいKeyを、ToLookup(Result => Result.address のように指定します。
上記の例では、もっと良いやり方があると思いますが、Listの”大阪”を重複要素として扱い、Dictionary型のKeyにグルーピングしています。

次に、dict.Keys.CopyTo() で Dictionary型のKeyを配列にコピーします。
コピーする理由はDictionary型だと、順番がランダムになるため、配列にコピーして Sort して forループの際に欲しい値を取り出すためです。

DictionaryのKeyに対応するValueを取り出す場合には、dict["大阪"][i].name で取り出すことができます。

Console.WriteLine("---values[i]---");
Console.WriteLine(values[i]);
//////////for文の実行結果
---values[i]---
大阪
---values[i]---
東京
---values[i]---
名古屋
Console.WriteLine("---dict[\"大阪\"][i].name---");
Console.WriteLine(dict["大阪"][i].name);
//////////for文の実行結果
---dict["大阪"][i].name---
田中
---dict["大阪"][i].name---
鈴木
---dict["大阪"][i].name---
鈴木

C#について学びたいという方は 世界最大級のオンライン学習サイトUdemy をおすすめします。

About
Amelt.net,LLCの創業者で、費用対効果の高い統合webマーケティングによりビジネスパートナーとして継続的にサポート。詳しいより。ブログの更新情報TwitterLinkedIn、またRSSfeedlyにてお知らせしていますのでフォローよろしくお願い致します。