アプリ版:「スタンプのみでお礼する」機能のリリースについて

Rubyで2次元のハッシュを扱いたいです。

perlで書くと以下のような感じです。(最近perlに疎遠なので自信無いですが^^;)

hash{$key1}{$key2}=$value;

foreach $key1 (keys %hash){
foreach $key2 (keys %{$hash{$key1}}){
print "$hash{$key1}{$key2}\n";
}
}

Rubyだとどんな感じになりますか?

A 回答 (3件)

たく面倒くせえなあ(笑)



何もせずに
hash{$key1}{$key2}=$value;
のような感じで
h[key1][key2]=val
ができないのをどうにかしたい、って書いてくれれば
ちゃんとそうやったのに。

h = Hash.new{|hash, key| hash[key] = {} }
while line = DATA.gets
key1,key2,val = line.split(/\s*,\s*/)
h[key1][key2]=val unless (key1.nil? or key2.nil? or val.nil?)
end

h.keys.each do |key1|
h[key1].keys.each do |key2|
puts "h[#{key1}][#{key2}]=#{h[key1][key2]}"
end
end


__END__
1,1,1
2,3,6
4,4,16
9,9,81

-------
h[1][1]=1
h[2][3]=6
h[4][4]=16
h[9][9]=81

これでいいですか?

この回答への補足

毎度、お世話になります。

切り取って実行してみると、以下エラーになってしまいます。

undefined method `[]=' for nil (NameError)

あと、一行目のところが理解できません。
h = Hash.new{|hash, key| hash[key] = {} }
の『= {} 』の意味を説明して頂けませんか?

補足日時:2007/11/07 20:15
    • good
    • 0

んー実行して結果を確かめてから書き込みしたんで


エラーが出るのは納得できないなあ。

C:\Users\>ruby190 -v moge.rb
ruby 1.9.0 (2007-11-05 patchlevel 0) [i386-mswin32_71]
mogera.rb:7: warning: shadowing outer local variable - key1
mogera.rb:8: warning: shadowing outer local variable - key2
h[1][1]=1
h[2][3]=6
h[4][4]=16
h[9][9]=81

C:\Users\>ruby186 -v moge.rb
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]
h[9][9]=81
h[1][1]=1
h[2][3]=6
h[4][4]=16

ご覧の通りエラーのえの字もありません。

> h = Hash.new{|hash, key| hash[key] = {} }
> の『= {} 』の意味を説明して頂けませんか?

これは空の無名ハッシュです。

変数を空の配列として初期化するときに
v = []
のようにできますが、それのハッシュ版です。
全体としてハッシュの初期化なので、= Hash.key }
のようにもう一回 Hash.new とかくのがいやだったので
そうしています。

この回答への補足

ruby 1.6.1を使用してた為みたいです。
ruby 1.8.6 に乗り換えたらエラーなしでした。
お騒がせしました。

因みに、キーが3つだったら、以下の様に書くんですね?
h = Hash.new{|hash, key| hash[key] =Hash.new{|hash, key| hash[key]={}} }

#perlの方が楽だと思ってしまいます。

補足日時:2007/11/07 22:39
    • good
    • 0

Perlの例に合わせるならこんな感じでしょうか



h = Hash.new

h['foo'] = Hash.new
h['bar'] = Hash.new
h['baz'] = Hash.new

h['foo']['xx'] = 1
h['foo']['yy'] = 2
h['bar']['zz'] = 3
h['bar']['aa'] = 4
h['baz']['bb'] = 5
h['baz']['cc'] = 6

h.keys.each do |key1|
h[key1].keys.each do |key2|
puts h[key1][key2]
end
end

この回答への補足

回答ありがとうございます。

ご回答頂いた例ですと、第一キーとなるfoo.bar,bazを予め知ってるって感じじゃないですか。

while line = DATA.gets
key1,key2,val = line.split(/\s*,\s*/)
h[key1][key2]=val
end
__END__
1,1,1
2,3,6
4,4,16
9,9,81

上記の様に書きたく、データのキーのバリエーションが変わっても対応できるようにしたいです。

補足日時:2007/11/07 10:06
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!