- - PR -
hashtable内にhashtableを入れたときのキー指定(追加登録)
1
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-02-07 14:22
C#初心者です。宜しくお願いします。
ハッシュテーブル(hash2)の中にハッシュテーブル(hash1)を入れる処理を行っています。 ハッシュテーブル(hash2)に既に存在するキーの値にハッシュテーブル(hash1)を 追加登録したのですが、指定のしかたがわかりません。 下記コードの☆の箇所で行いたいのですが、下記コードでは上書きされてしまいます。 そもそも、実現できるのかどうかも含めてどなたかご教授願います。 [コード] Hashtable Hash2 = new Hashtable(); string[] s3; //af(Hashtable)に入っている値 //1 キー:"Dtl,0,1" 値:"A" //2 キー:"Dtl,1,1" 値:"B" //3 キー:"Dtl,0,2" 値:"C" //Dtl 0 2 //↑ ↑ ↑ //形式 列 行 foreach (string key in af.Keys) { string afval = (string)af[key]; s3 = key.Split(','); Hashtable Hash1 = new Hashtable(); Hash1.Add(s3[2], afval); if (Hash2.ContainsKey(s3[1]) == false) { //キーがない場合 Hash2.Add(s3[1], Hash1); } else { //☆ キーが既に存在する場合 Hash2[s3[1]] = Hash1; } } | ||||||||||||
|
投稿日時: 2007-02-07 14:58
いまいち理解できていないのですが、上記コードを実行したときに、
Hash2[0]に格納されたHashTableに最後に追加された要素(キーが2で値が"C"のもの)しか 入っていないものと思われます。 そうではなくて、要素2つ(キーが1で値が"A"のものと、キーが2で値が"C"のもの)が 入るようにしたいという意味でしょうか? | ||||||||||||
|
投稿日時: 2007-02-07 15:07
返答ありがとうございます。
まったくその通りです。 VB6.0をやってたころはDictionaryObjectでできた気がするのですが... | ||||||||||||
|
投稿日時: 2007-02-07 15:27
foreachの1回目のループでは、Hash2にはキーが1で、
値は要素数1のHashTable(以下、HashTableAと呼ぶことにします)が追加されます。 ちなみにAの要素はキーが1、値がAのものになります。 3回目のループでは、Hash2.ContainsKey(1)はtrueを返すためelse句が処理されます。 なぜなら1回目のループで、キーが1の要素は既に追加されているからです。 ここまでは大丈夫ですよね? で、問題の3回目のループなのですが… Hash1という変数名でHashTableを生成していますが、 これはここで生成した新しいHashTableですから、HashTableAとは全くの別物です。 (以下、HashTableBと呼ぶことにします) Hash2[1] = HashTableBと書いているわけですから、 もともと格納されていたHashTableAは「上書き」されてしまうのです。 ですから、3回目のループではHashTableを新たに生成するのではなく、 既にHash2[1]に格納されているHashTableAを取得して、 その要素を「追加」してやるようにすれば上手くいくはずです。 | ||||||||||||
|
投稿日時: 2007-02-07 16:31
KIさん。ありがとうございました。 仰るとおり、Hash2[1]に格納されている要素を追加したらうまくいきました。 (下記 "◎追加") Hashtable Hash2 = new Hashtable(); string[] s3; //af(Hashtable)に入っている値 //1 キー:"Dtl,0,1" 値:"A" //2 キー:"Dtl,1,1" 値:"B" //3 キー:"Dtl,0,2" 値:"C" //Dtl 0 2 //↑ ↑ ↑ //形式 列 行 foreach (string key in af.Keys) { string afval = (string)af[key]; s3 = key.Split(','); Hashtable Hash1 = new Hashtable(); Hash1.Add(s3[2], afval); if (Hash2.ContainsKey(s3[1]) == false) { //キーがない場合 Hash2.Add(s3[1], Hash1); } else { //◎追加-------------------------------- Hashtable hash3 = new Hashtable(); hash3 = (Hashtable) Hash2[s3[1]]; foreach (string Akey in hash3.Keys) { string val = (string)hash3[Akey]; Hash1.Add(Akey, val); } Hash2[s3[1]] = Hash1; //◎追加-------------------------------- } } | ||||||||||||
|
投稿日時: 2007-02-07 17:05
うまくは行ったのかも知れませんが、コードにいくつか問題がありますので指摘しておきます。
上記コードだと、動作はするかも知れませんが無駄な処理が多いので、 レコードが増えるとパフォーマンスの低下が懸念されます。
上の行の「 = new Hashtable()」は不要です。 上の行で新しいHashTableを生成して、hash3という変数に格納していますが、 ここで生成したHashtableは全く使われることがありません。 何故だかわかりますか?
Hash3からHash1にコピーして、それをまた設定しているようですが、 そんなことをせずとも、Hash3に直接追加すればいいのです。 それに伴い、新しいHashtableをnewするのは、 新しい要素を追加するときだけでよくなります。 一応、foreach部分の修正したコードを載せておきますが 「オブジェクトをnewするとはどういうことか?」ですとか「値型と参照型の違い」ですとか、 基礎をしっかりと勉強されたほうがよいと思います。
#未確認なのでケアレスミスあったらすみません。 | ||||||||||||
|
投稿日時: 2007-02-07 17:46
上記、早速調べて見ました。 newすることで無駄に実体を作っていることに気づきました。 仰るとおり基礎をしっかりと勉強したいと思います。 KIさん、ご指摘どうもありがとうございました。 |
1