Quantcast
Channel: dictionaryタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 99

[C#]DictionaryのKeyをカスタムクラス、ValueをListにする

$
0
0
概要 業務にて、タイトルの通りカスタムクラスとLINQを組み合わせたDictionaryを使った実装が必要になったため、勉強と記録がてら記事作成します。 やりたいこと ざっくり、以下のような感じです。 (実際は全然違う内容ですが、便宜上置き換えています) 社員がノートに1行ずつ起票をしていく運用のノートがある。 ノートでは、同じ社員が複数行起票することがある。 このノートにおいて、各社員が何行目に起票したかを整理し、表示する。 上記において、 社員情報-記入した行のリスト という形のDictionayを使用することで対応しました。 ポイント Dictionaryにおいて、Keyを同一とみなすためには以下を満たす必要があるようです。 GetHashCodeの結果が同じであること Equalsの結果がtrueであること したがって、Keyに独自のクラスを使用する場合は、上記2つの関数を適切にオーバーライドする必要があります。 実装例 以下のような感じにしました。 ※とりいそぎで書いているので、最後のコンソール出力はソートせずにdictionaryに入れた順で出しちゃってます。 ※foreachのループの中でループカウンタをとってくる方法は、もっといいやり方があるかも… 社員クラス public class Employee { public string id { get; set; } public string name { get; set; } // コンストラクタ public Employee(string id, string name) { this.id = id; this.name = name; } // Equalsをオーバーライド(※VisualStudioで自動生成) public override bool Equals(object obj) { return obj is Employee employee && id == employee.id && name == employee.name; } // GetHashCodeをオーバーライド(※VisualStudioで自動生成) public override int GetHashCode() { int hashCode = -48284730; hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(id); hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(name); return hashCode; } } Main // 結果の格納先 Dictionary<Employee, List<int>> dictionary = new Dictionary<Employee, List<int>>(); // 社員群 Employee john1 = new Employee("A0001", "John"); Employee tom = new Employee("A0002", "Tom"); Employee john2 = new Employee("A0003", "John"); Employee emily = new Employee("A0004", "Emily"); Employee alex = new Employee("A0005", "Alex"); // 記帳順のリスト List<Employee> entryList = new List<Employee>() { john1, tom, john1, emily, alex, john2, john1, john2, alex }; List<int> valueList; int i = 0; Console.WriteLine("--- 記帳順 ---"); // 記帳順を格納していく foreach (Employee employee in entryList) { i++; // dictionaryに登録済かを判定しつつ、登録済の場合はリストを取得 if (dictionary.TryGetValue(employee, out valueList)) { // 登録済の場合、リストに値を追加して更新 valueList.Add(i); dictionary[employee] = valueList; } else { // 初出の場合、登録 dictionary.Add(employee, new List<int> { i }); } Console.WriteLine(string.Format("i={0}, {1}:{2}", i, employee.id, employee.name)); } Console.WriteLine("--- 社員ごとの記録 ---"); // 結果を出力 foreach (Employee employee in dictionary.Keys) { Console.WriteLine(string.Format("{0}:{1} - {2}", employee.id, employee.name, string.Join(", ", dictionary[employee]))); } 結果 --- 記帳順 --- i=1, A0001:John i=2, A0002:Tom i=3, A0001:John i=4, A0004:Emily i=5, A0005:Alex i=6, A0003:John i=7, A0001:John i=8, A0003:John i=9, A0005:Alex --- 社員ごとの記録 --- A0001:John - 1, 3, 7 A0002:Tom - 2 A0004:Emily - 4 A0005:Alex - 5, 9 A0003:John - 6, 8 参考リンク C#で自作クラス(カスタムクラス)をキーにする方法(Dictionary,HashSet)

Viewing all articles
Browse latest Browse all 99

Trending Articles