或るプログラマの開発日記

日々の勉強したことの備忘録なんかに使っていきます

Rubyでhashから値を取る方法のメモ

Rubyでhashを使ってて、Javaとかとは勝手が違っていたところで結構ハマッたので、調べた情報をメモ。

keyが文字列かシンボルか?

Rubyのhashはkeyとして文字列はもちろん、シンボルをkeyとして使うことも出来ます。例として、文字列、シンボルそれぞれをkeyとしたhashから値を取得するプログラムを書いてみます。

strhash={"key1" => "value1", "key2" => "value2", "key3" => "value3"}
symbolhash={key1: "value1", key2: "value2", key3: "value3"}
p strhash["key1"] # => "value1"
p strhash[:key1]  # => nil
  
p symbolhash["key1"]# => nil
p symbolhash[:key1] # => "value1"

もちろん、文字列とシンボルは中身が全然異なるので、それを混同するとおかしなことになります。keyが何の型かを認識しておかなければなりません。

fetchメソッドの仕様

先の例では[]を使って値を取得していましたが、fetchメソッドを使って値を取得することも出来ます。[]を使うのと、fetchを使うのとでは、hashから値が取れなかった時の扱いに大きな違いがあります。

単純なfetchメソッド

keyのみを引数とするfetchメソッドは、値が取れなかったときに例外が発生します。

symbolhash={key1: "value1", key2: "value2", key3: "value3"}
p symbolhash.fetch(:key1) # => "value1"
p symbolhash.fetch(:key4) # => `fetch': key not found: :key4 (KeyError)

値が絶対に取得できる前提で使うにはいいのかもしれませんね。

デフォルト値付きfetch()

第2引数にデフォルト値を渡すと、値が取れなかったときにデフォルト値が返却されます。

symbolhash={key1: "value1", key2: "value2", key3: "value3"}
p symbolhash.fetch(:key1, "not found") # => "value1"
p symbolhash.fetch(:key4, "not found") # => "not found"

[]で取るのと、fetch(key, nil)とは同じということですね。

ブロック付きfetch()

ブロックを渡すと、値が取れなかったときにブロックの値を評価した値が返却されます。

symbolhash={key1: "value1", key2: "value2", key3: "value3"}
p symbolhash.fetch(:key1){|key| key.to_s + " not found"} # => "value1"
p symbolhash.fetch(:key4){|key| key.to_s + " not found"} # => "key4 not found"

うーん。。正直使いどころが良く分からんが、まーこういう使い方も出来るということですね。

参考URL

stackoverflow.com