ハッシュのキーについて

少し調べたのでメモします。

実行環境

ruby 2.7.2
Rails 6.0.3.6

ハッシュリテラルについて

ハッシュのキーには、文字列よりシンボルの方が適していると言われています。
そのため、

{"a" => "b"}

より

{:a => "b"}

という書き方の方が良さそうです。 これは、

{a: "b"}

と同じです。こちらの方が矢印を省略できるのでシンプルです。

ちなみに、

:"a".class
# => Symbol

とあるように:"a"はシンボルのため以下の書き方もできます。

{:"a" => "b"}
{"a": "b"}

ハッシュのキーに空白や記号を含めたい場合は、上記のようにダブルクウォーテーションで囲みます。

{:"@a" =>  "b"}
{"@a": "b"}
{@a: "b"}  # これは SyntaxError となる

Rails でのハッシュ関連メソッド

いくつかRailsにおけるハッシュ関連メソッドを調べます。

symbolize_keys / stringify_keys

ruby の Hashクラスの to_hash や to_h はハッシュリテラルに対してselfを返します。キーについては、シンボルだったらシンボルのまま、文字列は文字列のままです。

{a: "b"}.to_hash
# => {:a =>"b"}
{"a" => "b"}.to_hash
# => {"a"=>"b"}

ここで、キーをシンボルに変換したい場合は symbolize_keys メソッドを使用します。

{"a" => "b"}.symbolize_keys
# => {:a =>"b"}

逆に、キーをシンボルから文字列に変換したい場合は stringify_keys メソッドを使用します。

{a: "b"}.stringify_keys
# => {"a"=>"b"}

with_indifferent_access

通常、キーに対応する値を取得したい場合は以下のように[key]を指定します。なお、該当のキーがない場合は nil を返します。

{a: "b"}[:a]
# => "b"
{a: "b"}[:c]
# => nil

この場合、キーを文字列で指定した場合は、値を取得できません。

{a: "b"}["a"]
# => nil

ここで with_indifferent_access メソッドを使うと、ハッシュのキーに関わらず、文字列やシンボルどちらを指定しても、値を取得することができるようになります。

hoge_hash = {a: "b"}.with_indifferent_access
hoge_hash["a"]
# => "b"

参考リンク

class Hash (Ruby 3.2 リファレンスマニュアル)
Hashの拡張機能