####ハッシュとシンボル
ハッシュは本質的には配列と同じ
インデックスとして整数値以外のものも使える点が配列と異なる
>> user = {} # {}は空のハッシュ
=> {}
>> user["first_name"] = "Michael" # キーが "first_name" で値が "Michael"
=> "Michael"
>> user["last_name"] = "Hartl" # キーが "last_name" で値が "Hartl"
=> "Hartl"
>> user["first_name"] # 要素へのアクセスは配列の場合と似ている
=> "Michael"
>> user # ハッシュのリテラル表記
=> {"last_name"=>"Hartl", "first_name"=>"Michael"}
ハッシュは、キーと値のペアを波カッコで囲んで表記
ハッシュの波カッコは、ブロックの波カッコとは違う。
ハッシュは配列と似ているが、重要な違いとして、ハッシュでは要素の「並び順」が保証されない
もし要素の順序が重要である場合は、配列を使う必要があり
>> user = { "first_name" => "Michael", "last_name" => "Hartl" }
=> {"last_name"=>"Hartl", "first_name"=>"Michael"}
キーと値をハッシュロケットと呼ばれる=> によってリテラル表現するほうが簡単
Rubyにおける慣習として、ハッシュの最初と最後に空白を追加
ハッシュのキーとして文字列を使っていましたが、Railsでは文字列よりもシンボルを使う方が普通
シンボルは文字列と似ていますが、クォートで囲む代わりにコロンが前に置かれている点
>> "name".split('')
=> ["n", "a", "m", "e"]
>> :name.split('')
NoMethodError: undefined method `split' for :name:Symbol
>> "foobar".reverse
=> "raboof"
>> :foobar.reverse
NoMethodError: undefined method `reverse' for :foobar:Symbol
>> :foo-bar
NameError: undefined local variable or method `bar' for main:Object
>> :2foo
SyntaxError
>> user = { :name => "Michael Hartl", :email => "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> user[:name] # :name に対応する値にアクセスする
=> "Michael Hartl"
>> user[:password] # 未定義のキーに対応する値にアクセスする
=> nil
未定義のハッシュ値は単純にnilである
>> h1 = { :name => "Michael Hartl", :email => "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> h2 = { name: "Michael Hartl", email: "michael@example.com" }
=> {:name=>"Michael Hartl", :email=>"michael@example.com"}
>> h1 == h2
=> true
シンボルとハッシュロケットの組み合わせを、次のようにキーの名前の(前ではなく)後にコロンを置き、その後に値が続くように置き換えたもの
{ name: "Michael Hartl", email: "michael@example.com" }
{ :name => "Michael Hartl" }
と{ name: "Michael Hartl" }
は同じ。
######ハッシュの中のハッシュ
>> params = {} # 'params' というハッシュを定義する ('parameters' の略)。
=> {}
>> params[:user] = { name: "Michael Hartl", email: "mhartl@example.com" }
=> {:name=>"Michael Hartl", :email=>"mhartl@example.com"}
>> params
=> {:user=>{:name=>"Michael Hartl", :email=>"mhartl@example.com"}}
>> params[:user][:email]
=> "mhartl@example.com"
Railsでは、このようなハッシュのハッシュ(またはネストされたハッシュ)が大量
>> flash = { success: "It worked!", danger: "It failed." }
=> {:success=>"It worked!", :danger=>"It failed."}
>> flash.each do |key, value|
?> puts "Key #{key.inspect} has value #{value.inspect}"
>> end
Key :success has value "It worked!"
Key :danger has value "It failed."
eachメソッドでは、ブロックの変数は1つだけですが、ハッシュのeachメソッドでは、ブロックの変数はキーと値の2つになっていることに注意
>> puts (1..5).to_a # 配列を文字列として出力
1
2
3
4
5
>> puts (1..5).to_a.inspect # 配列のリテラルを出力
[1, 2, 3, 4, 5]
>> puts :name, :name.inspect
name
:name
>> puts "It worked!", "It worked!".inspect
It worked!
"It worked!"
オブジェクトを表示するためにinspectを使うことは非常によくあることなので、 pメソッドというショートカット
>> p :name # 'puts :name.inspect' と同じ
:name
###演習
1.ハッシュを作れ
>> a = { 'one' => 'uno', 'two' => 'dos', 'three' => 'tres' }
=> {"one"=>"uno", "two"=>"dos", "three"=>"tres"}
>> a.each do |key,value|
?> puts "#{key}のスペイン語は#{value}"
>> end
oneのスペイン語はuno
twoのスペイン語はdos
threeのスペイン語はtr
2.3つのハッシュを作成,キーを追加し、適当な値,ハッシュのハッシュの作成,ハッシュのハッシュを調べていき、正しい値を表示しろ
>> person1 = { :first => 'rinngo', :last => 'gorira' }
=> {:first=>"rinngo", :last=>"gorira"}
>> person2 = { :first => 'rappa', :last => 'panntu' }
=> {:first=>"rappa", :last=>"panntu"}
>> person3 = { :first => 'tumiki', :last => 'kitutuki' }
=> {:first=>"tumiki", :last=>"kitutuki"}
>> params = {}
=> {}
>> params[:father] = person1
=> {:first=>"rinngo", :last=>"gorira"}
>> params[:mother] = person2
=> {:first=>"rappa", :last=>"panntu"}
>> params[:child] = person3
=> {:first=>"tumiki", :last=>"kitutuki"}
>> params[:father][:first]
=> "rinngo"
3.ハッシュを定義しろ
>> user = {}
=> {}
>> user[:name] = "irohanihoheto"
=> "irohanihoheto"
>> user[:email] = "tirinuruwo.com"
=> "tirinuruwo.com"
>> user[:password_digest] = ("a".."z").to_a.shuffle[0..15].join
=> "zpgxqoifcmsrnayb"
>> user
=> {:name=>"irohanihoheto", :email=>"tirinuruwo.com", :password_digest=>"zpgxqoifcmsrnayb"}
("a".."z")..to_a.shuffle[0..15].join
でランダムな十六文字の文字列を作成できた。
4.merge
メソッドの意味、{ "a" => 100, "b" => 200 }.merge({ "b" => 300 })
がどういう結果を示すか?
mergeは複数のハッシュを結合させるメソッドらしい。
このことから
{ "a" => 100, "b" => 300 }
という結果が返ってくると予測する
>> { "a" => 100, "b" => 200 }.merge({ "b" => 300 })
=> {"a"=>100, "b"=>300}
予測と合ってた。よかった。