■ 使用上の注意
★重要★ Dictionary へのデータ追加について
* dict.Add() と dict[] だと、キーが重複してた際に以下のような違いがある ~~~~~ [1] dict.Add() の場合、例外が発生(以下「※例外内容」を参照) [2] dict[]の場合、上書き※例外内容
System.ArgumentException : 同一のキーを含む項目が既に追加されています追記:ToDictionary()の動作について
* 以下のサイトによると、ToDictionary()でも例外が発生するらしいhttps://qiita.com/YSRKEN/items/b4bad929fe49e38faa26
■ Dictionaryをマージする
* Linq / Concat / ToDictionary を使う ~~~~ var dictResults = dictNew.Concat( dictOld.Where(pair =>!dictNew.ContainsKey(pair.Key))) .ToDictionary(pair => pair.Key, i => pair.Value); ~~~~
サンプル
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace SampleForm { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { var dictOld = new Dictionary<string, int> { { "Key11", 101 }, { "Key12", 102 }, { "Key13", 103 } }; var dictNew = new Dictionary<string, int> { { "Key21", 201 }, { "Key12", 202 }, { "Key13", 203 }, { "Key24", 204 } }; var dictResults = dictNew.Concat( dictOld.Where(pair =>!dictNew.ContainsKey(pair.Key))) .ToDictionary(pair => pair.Key, i => pair.Value); foreach (var result in dictResults) { this.label1.Text = this.label1.Text + $"{result.Key} {result.Value}" + "\n"; } } } }出力結果
Key21 201 Key12 202 Key13 203 Key24 204 Key11 101
参考文献
https://qiita.com/Nossa/items/802b0e0de927c0cfec05■ DictionaryをValueからKeyを逆引きする
* Linqを使う
サンプル
using System.Linq; private void button10_Click(object sender, EventArgs e) { Dictionary<string, string> dictionaries = new Dictionary<string, string>() { {"appliance", "機器"}, {"proceed", "売り上げ"}, {"state-of-the-art", "最新の"}, {"recognize", "認める"}, {"production", "製品"}, }; this.label1.Text = this.GetKeyByValue(dictionaries, "最新の"); } private string GetKeyByValue(Dictionary<string, string> dictionaries, string value) { return dictionaries.FirstOrDefault(x => x.Value == value).Key; }
■ DictinaryのKeyを、リストとして取得する
* 「IList<string> list = dictionaries.Select(c => c.Key).ToList();」で可能
サンプル
private void button1_Click(object sender, EventArgs e) { Dictionary<string, string> dictionaries = new Dictionary<string, string>() { {"appliance", "機器"}, {"proceed", "売り上げ"}, {"state-of-the-art", "最新の"}, {"recognize", "認める"}, {"production", "製品"}, }; var list = dictionaries.Select(c => c.Key).ToList(); string result = string.Empty; foreach (var stringData in list) { result = result + "\n" + stringData; } this.label1.Text = result; }
■ DictinaryにTypeを登録する
* Dictinaryには、クラスなども登録できるので便利 * Type、typeof()、GetType()などについては、以下を参照http://blogs.yahoo.co.jp/dk521123/19117857.html
サンプル
Dictionary<Type, string> dictionaries = new Dictionary<Type, string> { {typeof(Form), "フォーム"}, {typeof(Button), "ボタン"}, {typeof(Label), "ラベル"}, }; this.label1.Text = dictionaries[this.button1.GetType()];
■ DictinaryにDictinaryを設定
* Dictinary内にDictinaryを設定できる
サンプル
* Dictinary/Dictinary(この例ではaddressBooks)にデータがなかったら、 住所データをDictinary/Dictinaryにデータ追加Form1.cs (メインプログラム)
public partial class Form1 : Form { public readonly Dictionary<NameOfUniversity, Dictionary<Department, string>> addressBooks; public Form1() { InitializeComponent(); // http://blogs.yahoo.co.jp/dk521123/20513549.html を参照 this.comboBox1.DataSource = Enum.GetValues(typeof(NameOfUniversity)); this.comboBox2.DataSource = Enum.GetValues(typeof(Department)); addressBooks = new Dictionary<NameOfUniversity, Dictionary<Department, string>> { { NameOfUniversity.Tokyo, new Dictionary<Department, string> { { Department.Literature, "東京都XX区XX-X" }, { Department.Science, "東京都XX区YY-X" }, } }, { NameOfUniversity.KO, new Dictionary<Department, string> { { Department.Literature, "東京都ZX区XY-Z" }, } }, }; } private void button7_Click(object sender, EventArgs e) { var name = (NameOfUniversity)this.comboBox1.SelectedValue; var department = (Department)this.comboBox2.SelectedValue; if (addressBooks.ContainsKey(name) && addressBooks[name].ContainsKey(department)) { // addressBooks内の住所データをラベルに表示 this.label1.Text = addressBooks[name][department]; } else { DialogResult result = MessageBox.Show( this, "単語帳に単語が見つかりませんでした。\n新規に単語を登録しますか?", "Not Found", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); if (result != DialogResult.Yes) { return; } // addressBooks内の住所データを登録 if (addressBooks.ContainsKey(name)) { // addressBooks内に存在する大学名の住所データを登録 addressBooks[name][department] = this.textBox1.Text; } else { // addressBooks内に存在しない大学名の住所データを登録 addressBooks.Add(name, new Dictionary<Department, string> { { department, this.textBox1.Text }, }); } } } }NameOfUniversity.cs (使用しているEnum [1])
public enum NameOfUniversity { None, Tokyo, Waseda, KO, }Department.cs (使用しているEnum [2])
public enum Department { None, Literature, Science, Medical, }
関連記事
C# / コレクション
List (リスト)https://blogs.yahoo.co.jp/dk521123/22295813.html
Concurrentコレクション ~ スレッドセーフなコレクション ~
https://blogs.yahoo.co.jp/dk521123/38017014.html
BlockingCollection ~ Producer-Consumerパターン ~
https://blogs.yahoo.co.jp/dk521123/37943991.html
その他
【VB】C#との差異 (ジェネリック、List、Dictionary 編)https://blogs.yahoo.co.jp/dk521123/28112686.html