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 をおすすめします。