※ カリキュラムでは、Cloud9のエディタやターミナルを利用します。
まだ用意していない方は「AWS Cloud9を準備しよう」を参考に導入してください。
ハッシュのイメージを図で掴もう
まずは「ハッシュとは何か」を図で理解していきましょう。
ハッシュ(Hash)とは
ハッシュとは任意のオブジェクトを使って、複数のデータ(オブジェクト)への参照をまとめて管理できるオブジェクトのことです。
ハッシュと似たような存在として、配列があります。
配列も「複数のデータへの参照をまとめて管理できるオブジェクト」だと学びましたね。
配列の場合は、名札に0からの番号が自動で順番に割り当てられます。
ハッシュの場合は、名札の名前を自由に付けることができます。
以下の図のように、ハッシュは配列と同様に複数の名札が連結して並べられていますが、名札には文字列などの任意のオブジェクトを使って、自由に名前を付けることができます。
上の図では、"name"
や"age"
などの文字列を使い、名札に名前を付けています。
文字列や数値など複数の種類のオブジェクトを格納する場合は、「番号で管理する配列」よりも「自由に名前を付けられるハッシュ」の方が管理しやすいです。
ハッシュの要素
ハッシュの中の名札は「要素」と呼ばれます。
Rubyでは、各要素はオブジェクトのことを指し示しています。
要素を特定することで、オブジェクトを参照することができます。要素の特定には、「キー」と呼ばれるものを使います。
ハッシュのキー
要素に割り当てた任意のオブジェクトは「キー」と呼ばれます。
各要素を特定するために「キー」が使われます。
キーを指定することで、キーに対応するオブジェクトを参照することができます。
配列の場合は「添字」だったけど、ハッシュの場合は「キー」なんだね!
ハッシュは変数に代入できる
ハッシュ自体もオブジェクトなので、変数に代入することができます。
ハッシュを変数に代入すると、以下の図のように1人の男性のデータを管理するハッシュに対してuser
と名付けることができます。
変数に代入したオブジェクトは、変数名を指定することで参照することができましたが、ハッシュを代入した場合は、どのように指定すればよいでしょうか。
以下の図のように変数名(user
)だけでは、ハッシュ自体を指していることになり、各要素の値を参照することができません。
そこで、要素を特定することができる「キー」の登場です。
変数名に加えて「キー」を指定することで、キーに対応するオブジェクトを参照することができます。
ハッシュのイメージが掴めたところで、次はRubyを使ってハッシュを学ぼう
ハッシュの生成方法とは
ハッシュの作り方について学んでいきましょう。
ハッシュの生成方法
ハッシュは、{}
で生成することができます。
以下の書き方では、何もデータを持たない空のハッシュが生成されます。
1
{}
キーと値の組み合わせを格納するハッシュを生成するには、以下のように記述します。
キーと値は=>
を使って対応付けます。
1
{ キー => 値 }
以下のように,
で区切ることで、複数のキーと値の組み合わせが格納できます。
1
{ キー1 => 値1, キー2 => 値2, キー3 => 値3 }
また、以下の赤い箇所のように「半角スペース」を{
の後や}
の前、=>
前後、カンマ(,
)の後に入れることで、コードが読みやすくなります。
さらに改行して記述することもできます。
1
2
3
4
5
{
キー1 => 値1,
キー2 => 値2,
キー3 => 値3
}
それでは、前述の例を使ってハッシュの生成方法を確認してみよう
図とコードでハッシュの生成方法を確認しよう
前述の例で使用した図を使って、ハッシュの生成方法を確認してみましょう。
キーと値の対応付けは、以下のようになります。
上の図をソースコードにする場合は、以下のようにキーと値を指定します。
1
{ "name" => "田中 太郎", "age" => 18, "gender" => "男" }
改行する場合は、以下のように書きます。
1
2
3
4
5
{
"name" => "田中 太郎",
"age" => 18,
"gender" => "男"
}
次は実際に手を動かしてハッシュを生成していこう!
ハッシュを生成してみよう
それでは、実際にハッシュを生成してみましょう。
irbを起動して、以下のコードを順番に実行しましょう。
1
{}
1
{ "name" => "田中 太郎" }
1
{ "name" => "田中 太郎", "age" => 18, "gender" => "男" }
上記をirbで実行すると、以下の画像のように生成されたハッシュが返ります。
次は、ハッシュを変数に代入してみます。
ハッシュを変数に代入
ハッシュはHashクラスのオブジェクトなので、変数に代入することができます。
1
変数名 = ハッシュオブジェクト
ハッシュを変数に代入すると、以下の図のようにある1人のデータを管理するハッシュに対してuser
と名付けることができます。
上の図をソースコードにする場合は、以下のように左辺に変数名、右辺にハッシュオブジェクトを指定します。
1
user = { "name" => "田中 太郎", "age" => 18, "gender" => "男" }
ハッシュを変数に代入してみよう
irbを起動して、変数(user
)に1人の情報をまとめたハッシュを代入してみましょう。
1
user = { "name" => "田中 太郎", "age" => 18, "gender" => "男" }
ハッシュを変数に代入したら、動画のように変数名でハッシュを参照してみましょう。
user
でハッシュオブジェクトを参照することができましたね。
次はハッシュの基本的な使い方を学ぶよ!
ハッシュの基本的な使い方を学ぼう
ハッシュの基本的な使い方について学んでいきましょう。
ここからは、Rubyのファイルを使います。
hash.rbという名前のファイルを作成して、以下の内容を記述しておきましょう。
※ファイルは「pikawakaフォルダ」の直下に作成しましょう。
1
user = { "name" => "田中 太郎", "age" => 18, "gender" => "男" }
上記をCloud9のエディタに記述すると、警告マークが表示されます。
「定義した変数がエディタ上のどこにも使用されていない」という警告なので、現時点では気にする必要はありません。
それでは、「要素の参照・変更・追加・削除・繰り返し」を順番に学んでいきましょう。
要素の値を参照する
ハッシュから値を参照するには、以下のようにキーを指定します。
1
ハッシュ[キー]
1
2
{ "name" => "田中 太郎" }["name"]
#=> "田中 太郎"
ただ、ハッシュは変数に代入して使いまわすことが多いので、上のような直接的な書き方はあまりしません。
変数を使う場合は、ハッシュを代入した変数名の後に[]
でキーを指定します。
1
2
変数名 = ハッシュ
ハッシュの変数名[キー]
前述の例で使用した図を使って、ハッシュの値の参照を確認してみましょう
変数user
に代入したハッシュの値("田中 太郎"
)を参照するには、変数名だけではなくキー("name"
)を指定する必要があります。
上の図をソースコードにすると、以下のようになります。
1
2
3
4
user = { "name" => "田中 太郎", "age" => 18, "gender" => "男" }
user["name"] #変数名[キー]
#=> "田中 太郎"
user["name"]
でキーである"name"
に対応する"田中 太郎"
が参照できます。
またハッシュを変数に代入することによって、user["name"]
だけで「ユーザーの名前を参照している」と意味が伝わりますね。
それでは実際にhash.rbでキーの値を参照してみよう
要素の値を参照してみよう
キーである"age"
に対応する値の18
を参照してみましょう。
hash.rbにハイライト箇所を記述してみましょう。
1
2
3
user = { "name" => "田中 太郎", "age" => 18, "gender" => "男" }
p user["age"]
続いて、動画のようにrubyコマンドでhash.rb
を実行してみましょう。
実行すると、キーとして指定した"name"
に対応付けられる18
が出力されましたね。
このように各要素の値を参照するときは、[]
と「キー」を使います。
要素の値を追加・変更する
ハッシュのキーと値を新しく追加するには、以下のように記述します。
新しく追加したキーと値は、ハッシュの最後に追加されます。
1
ハッシュ[キー] = 新しい値
例えば、身長が183という情報を追加する場合は、以下のようにキーを"height"
に指定して右辺に新しく追加する値を記述します。
1
2
3
4
5
6
7
user = { "name" => "田中 太郎", "age" => 18, "gender" => "男" }
user["height"] = 183
#=> 183
user
#=> {"name"=>"田中 太郎", "age"=>18, "gender"=>"男", "height"=>183}
user
を実行すると、ハッシュの最後に"height"=>183
が追加されていますね。
存在するキーを指定した場合は、値が上書きされます。
1
2
3
4
5
6
7
user = { "name" => "田中 太郎", "age" => 18, "gender" => "男" }
user["name"] = "佐藤 一郎"
#=>"佐藤 一郎"
user
#=> {"name"=>"佐藤 一郎", "age"=>18, "gender"=>"男"}
user
には"name"
というキーが既に存在しています。
そのため、上の例では"name"
に対応する値が"田中 太郎"
から"佐藤 一郎"
に上書きされます。
実際にキーと値を追加・変更してみよう
キーと値を新しく追加してみよう
まずはハッシュに新しくキーと値を追加してみましょう。
体重の情報として、キーである"weight"
に対応する値の76
を追加します。
hash.rb
にハイライト箇所を記述してみましょう。
1
2
3
4
5
user = { "name" => "田中 太郎", "age" => 18, "gender" => "男" }
p user
user["weight"] = 76
p user
続いて、動画のようにrubyコマンドでhash.rb
を実行してみましょう。
実行すると、ハッシュの最後に"weight" => "76"
が追加されましたね。
キーの値を変更してみよう
次にハッシュの値を変更してみましょう。
キーである"age"
を指定して、年齢を18
から50
に変更します。
ハイライトが当たる部分をhash.rbで編集してみましょう。
1
2
3
4
5
6
7
8
9
user = { "name" => "田中 太郎", "age" => 18, "gender" => "男" }
# p user
user["weight"] = 76
# p user
p user["age"]
user["age"] = 50
p user["age"]
続いて、動画のようにrubyコマンドでhash.rb
を実行してみましょう。
実行すると、"age"
に対応する値が18
から50
に上書きされましたね。
要素の値を削除する
ハッシュから値を削除するには、deleteメソッドを使います。
deleteメソッドの()
内には削除する値のキーを指定します。
1
ハッシュ.delete(キー)
例えば、ハッシュ内の"男"
という値を削除する場合は、キーである"gender"
をdeleteメソッドの()
内に指定します。
1
2
3
4
5
6
7
user = { "name" => "田中 太郎", "age" => 18, "gender" => "男" }
user.delete("gender")
#=> gender
user
#=> {"name"=>"田中 太郎", "age"=>18}
要素の値を削除してみよう
それではdeleteメソッドを使って、ハッシュ内の値を削除してみましょう。
deleteメソッドにキーの"age"
を指定して、年齢の情報を削除します。
ハイライトが当たる部分をhash.rbで編集してみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
user = { "name" => "田中 太郎", "age" => 18, "gender" => "男" }
# p user
user["weight"] = 76
# p user
# p user["age"]
user["age"] = 50
# p user["age"]
user.delete("age")
p user["age"]
p user
続いて、動画のようにrubyコマンドでhash.rb
を実行してみましょう。
存在しないキーを指定した場合は、nil
が返ります。
deleteメソッドによって、"age"
も含めて対応する値は削除されています。
そのため、削除後に参照しようとしても"age"
は存在しないのでnil
を返します。
要素分を繰り返す
ハッシュからキーと値を順番に取り出すには、eachメソッドを使います。
配列でもeachメソッドを使いましたが、ハッシュの場合はブロックの変数1
に「キー」、変数2
にキーに対応する「値」が順番に渡されます。
ブロック内ではキーと値が入った変数1
と変数2
が使用できます。
1
2
3
ハッシュ.each do |変数1, 変数2|
#繰り返したい処理
end
例えば、"キー : 値"
のようにキーと値を文字列にして出力させます。
以下のようにブロック内で各変数(key
・value
)と式展開を利用します。
1
2
3
4
5
6
7
8
9
user = { "name" => "田中 太郎", "age" => 18 }
user.each do |key, value|
p "#{key} : #{value}"
end
#出力結果
"name : 田中 太郎"
"age : 18"
eachメソッドによって、ハッシュにキーが追加された順番に取り出されます。
ソースコードだけでは少し難しいので、図を使って処理の流れを整理していきます。
処理の流れを整理しよう
以下のサンプルコードの流れを図で1つ1つ説明します。
1
2
3
4
5
user = { "name" => "田中 太郎", "age" => 18 }
user.each do |key, value|
p "#{key} : #{value}"
end
eachメソッドは、ハッシュにキーが追加された順番、つまりキーと値を最初から順番に取り出してブロックに渡します。
最初にハッシュ内の"name"
と"田中 太郎"
を取り出し、key
とvalue
に渡されます。
次に、ブロック内の処理が実行されます。
式展開の結果が出力されます。
このときブロック内のkey
とvalue
は、"name"
と"田中 太郎"
を参照します。
ハッシュには要素がまだ存在するので、eachメソッドは次のキーと値("age"
・18
)を取り出して、各変数に渡します。そして、同様にブロック内の処理が実行されます。
このときブロック内のkey
とvalue
は、"age"
と18
を参照します。
このように最後の要素になるまで、処理が繰り返されます。
実際にeachメソッドとブロックを使ってみよう!
eachメソッドとブロックを使ってみよう
eachメソッドとブロックを使って、ハッシュの繰り返し処理を行いましょう。
ハイライが当たる箇所をhash.rbに書きましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
user = { "name" => "田中 太郎", "age" => 18, "gender" => "男" }
# p user
user["weight"] = 76
# p user
# p user["age"]
user["age"] = 50
# p user["age"]
user.delete("age")
# p user["age"]
p user
user.each do |key, value|
p "キーは#{key}で、値は#{value}です。"
end
続いて、動画のようにrubyコマンドでhash.rb
を実行してみましょう。
key
とvalue
には、ハッシュの中身が順番に渡されます。そのため、ブロック内の処理も先頭のキーと値から出力されます。
キーには「シンボル」を使う
ハッシュのキーには、これまで使用してきた文字列以外にも「任意のオブジェクト」を指定することができます。
文字列以外でキーとしてよく使われるのが、シンボルというオブジェクトです。
シンボルは「Symbolクラス」のオブジェクトで、セミコロン:
を使います。
1
2
3
4
5
"name".class
#=> String
:name.class
#=> Symbol
シンボルは文字列よりも実行の速度が速いのため、ハッシュのキーには文字列よりもシンボルが推奨されます。
ハッシュのキーにシンボルを使う
ハッシュのキーにシンボルを使うには、先頭にセミコロン:
を付けます。
基本的には文字列のように扱うことができます。
1
{ "name" => "田中 太郎", "age" => 18 }
1
{ :name => "田中 太郎", :age => 18 }
hash.rb
の1行目にあるハッシュのキーを文字列からシンボルに変更してみましょう。
1
2
3
user = { "name" => "田中 太郎", "age" => 18, "gender" => "男" }
# p user
#省略...
1
2
3
user = { :name => "田中 太郎", :age => 18, :gender => "男" }
# p user
#省略...
シンボルを使って=>を省略する
ハッシュのキーにシンボルを使うと、=>
を省略することができます。
=>
を省略する場合は、シンボルのセミコロンの位置が変わります。
オブジェクトの「左側」に付くセミコロンは、オブジェクトの「右側」に付けます。
1
{ :name => "田中 太郎", :age => 18 }
1
{ name: "田中 太郎", age: 18 }
「シンボル:」と「値」の間には、半角スペースを入れます。
セミコロンが左にある場合は、=>
を省略することができないので注意してください。
それでは、hash.rb
の1行目を変更して=>
を削除してみましょう。
1
2
3
user = { :name => "田中 太郎", :age => 18, :gender => "男" }
# p user
#省略...
1
2
3
user = { name: "田中 太郎", age: 18, gender: "男" }
# p user
#省略...
続いて、コード変更後に正しく動作するかを確かめます。
動画のようにrubyコマンドでhash.rb
を実行しましょう。
エラーが発生することなく動作すれば、きちんと変更できています。
シンボルを使って値を参照する
ハッシュのキーがシンボルの場合は、以下のように指定して値を参照します。
[]
の中のセミコロンは左にします。
1
ハッシュ[:シンボル]
1
2
3
4
user = { name: "田中 太郎", age: 18 }
user[:name]
#=> "田中 太郎"
以下のように指定することで、キーと値を新しく追加したり、キーが存在すれば上書きすることもできます。
1
ハッシュ[:シンボル] = 新しい値
1
2
3
4
5
user = { name: "田中 太郎", age: 18 }
user[:name] = "山田 花子"
p user[:name]
#=> "山田 花子"
それでは、hash.rb
を編集してみましょう。
ハッシュのキーが文字列になっている箇所は、全てシンボルに変えましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
user = { name: "田中 太郎", age: 18, gender: "男" }
# p user
user["weight"] = 76
# p user
# p user["age"]
user["age"] = 50
# p user["age"]
user.delete("age")
# p user["age"]
p user
user.each do |key, value|
p "キーは#{key}で、値は#{value}です。"
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
user = { name: "田中 太郎", age: 18, gender: "男" }
# p user
user[:weight] = 76
# p user
# p user[:age]
user[:age] = 50
# p user[:age]
user.delete(:age)
# p user[:age]
p user
user.each do |key, value|
p "キーは#{key}で、値は#{value}です。"
end
rubyコマンドでhash.rb
を実行して、エラーが発生しなければ無事に変更することができています。
ハッシュのキーには、文字列ではなくシンボルを積極的に使いましょう
ハッシュの応用的な使い方を学ぼう
入れ子構造のハッシュ
ハッシュの値には、これまで使用してきた文字列や数値以外にも「任意のオブジェクト」を指定することができます。
ハッシュは、Hashクラスのオブジェクトです。
そのため、ハッシュ自体もハッシュのキーに対応付けた値として格納することができます。
1
{ name: { last: "田中", first: "太郎" }, age: 18 }
ハッシュの{ last: "田中", first: "太郎" }
は、name:
のキーに対応付けた値として格納されています。
上の入れ子構造のハッシュのように、キーに対応付ける値として「別のハッシュ」を格納することができます。
入れ子構造のハッシュから値を参照するには、以下のように指定します。
1
ハッシュ[キー][入れ子のキー]
1
2
3
4
user = { name: { last: "田中", first: "太郎" }, age: 18 }
user[:name][:last]
#=> "田中"
指定するキーのシンボルは、どちらもセミコロンを左にします。
この記事のまとめ
- ハッシュは、複数のオブジェクトへの参照をまとめて管理できる
- ハッシュは、複数の名札が連結して自由に名前を付けられるイメージ
- 複数の種類のオブジェクトを格納する場合は、配列よりもハッシュの方が識別しやすい
この記事で学んだことをTwitterに投稿して、アウトプットしよう!
Twitterの投稿画面に遷移します