身の回りにあるものや人には様々な性質が備わっている。 そのような性質を記す方法は様々なところで用いられている。
特定のキャラクタに対する属性を管理する場合を考える。 たとえば以下の一覧にあるものを表現したい。
| [0] | |
       
      | |
| 名前 | ドナポン | 
|---|---|
| 属性 | 甘 | 
| 最大MP | 250 | 
| 初期MP | 20 | 
| [1] | |
       
      | |
| 名前 | ラジャイン | 
|---|---|
| 属性 | 土 | 
| 最大MP | 450 | 
| 初期MP | 2 | 
| [2] | |
       
      | |
| 名前 | リッタン | 
|---|---|
| 属性 | 沼 | 
| 最大MP | 150 | 
| 初期MP | 30 | 
| [3] | |
       
      | |
| 名前 | 音助 | 
|---|---|
| 属性 | 波 | 
| 最大MP | 100 | 
| 初期MP | 80 | 
図: キャラクタ集の例
上記の最初のキャラクタの場合、
という関係性を持つ。このように、特定のキーワードに対応する値を持つ 関係性の集合をハッシュといいう。 ここで、各関係の左辺にある元となるキーワードのことをキー(key)、 右辺にある対応値のことをバリュー(value)という。 上の例では以下のようになる。
| キー | バリュー | 
|---|---|
| "名前" | "ドナポン" | 
| "属性" | "甘" | 
| "最大MP" | 250 | 
| "初期MP" | 20 | 
Rubyではこの対応関係を
{キー1 => バリュー1, キー2 => バリュー2, ...}
の形式で表す。上のキャラクタ例は以下のように表現する(値の部分の文字列と数値の違いに注意)。
{"名前" => "ドナポン", "属性" => "甘", "最大MP" => 250, "初期MP" => 20}
この値を何らかの変数に入れて処理することになる。
変数aに入れて、「名前」に対応する値を取り出すには以下のようにする(実際にirbで試してみること)。
irb a = {"名前" => "ドナポン", "属性" => "甘", "最大MP" => 250, "初期MP" => 20} a["名前"] => "ドナポン"
このように、ハッシュを持っている変数にキーを添え字に指定すると バリューを取り出せる。
逆に、値を設定するときは添字付きで代入する。
a["最大MP"] = 350 => 350 a => {"名前"=>"ドナポン", "属性"=>"甘", "最大MP"=>350, "初期MP"=>20}
ハッシュ形式の値はプログラムを書くときに定まるものだけではない。 たとえば以下のような新キャラクタを、プログラム実行後に利用者に 好きな値を入力して決めてよいことにしたい場合を考える。
| [3] | |
       
      | |
| 名前 | ??? | 
|---|---|
| 属性 | ??? | 
| 最大MP | ??? | 
| 初期MP | ??? | 
このような場合は、キーとバリューのペアを一つも持っていない 空のハッシュ値 を入れてから代入させる。
newchar = {} # {} が空のハッシュ値 print "名前は何にしますか?: " newchar["名前"] = gets.chomp print "属性は何にしますか?: " newchar["属性"] = gets.chomp print "最大MPはいくつにしますか?: " newchar["最大MP"] = gets.to_i print "初期MPはいくつにしますか?: " newchar["初期MP"] = gets.to_i
空のハッシュ値は Hash.new でも生成できる。
newchar = Hash.new		# newchar = {} と同じ
ハッシュ形式の値のことをハッシュオブジェクトといい、
Hash.new で空のハッシュオブジェクトが生成できる。
#!/usr/koeki/bin/ruby
# -*- coding: utf-8 -*-
newchar = Hash.new			# newchar = {} と同じ
print "名前は何にしますか?: "
newchar["名前"] = gets.chomp
print "属性は何にしますか?: "
newchar["属性"] = gets.chomp
print "最大MPはいくつにしますか?: "
newchar["最大MP"] = gets.to_i
print "初期MPはいくつにしますか?: "
newchar["初期MP"] = gets.to_i
puts newchar
newchar.rbを保存して動かしてみよ。
./newchar.rb
名前は何にしますか?: たむどん
属性は何にしますか?: 沼
最大MPはいくつにしますか?: 999
初期MPはいくつにしますか?: 10
{"名前"=>"たむどん", "属性"=>"沼", "最大MP"=>999, "初期MP"=>10}
bに代入する文を書け。cに代入する文を書け。ymgtに代入する文を書け。
 irbで実行して確認すること。aktに代入する文を書け。
 irbで実行して確認すること。※都道府県ごとの人口は 総務省:住民基本台帳に基づく人口、人口動態及び世帯数 の「住民基本台帳人口・世帯数、令和4年人口動態(都道府県別)」 などを参考にするとよい。
ハッシュ値は一つの個体の性質の集合を表すことができる。 一般的には個体が複数存在するので、これらを配列の形で表現することが多い。
図1の[0]から[3]の4つのキャラクタは 以下のようにハッシュ表現できる。
# [0]
{"名前" => "ドナポン", "属性" => "甘", "最大MP" => 250, "初期MP" => 20}
# [1]
{"名前" => "ラジャイン", "属性" => "土", "最大MP" => 450, "初期MP" => 2}
# [2]
{"名前" => "リッタン", "属性" => "沼", "最大MP" => 150, "初期MP" => 30}
# [3]
{"名前" => "音助", "属性" => "波", "最大MP" => 100, "初期MP" => 80}
4つの各値を要素とする配列にする。つまり、
[ハッシュ値1, ハッシュ値2, ハッシュ値3, ハッシュ値1]
の形式で並べると以下のようになる。
[ {"名前" => "ドナポン", "属性" => "甘", "最大MP" => 250, "初期MP" => 20}, # ←カンマに注意 {"名前" => "ラジャイン", "属性" => "土", "最大MP" => 450, "初期MP" => 2}, {"名前" => "リッタン", "属性" => "沼", "最大MP" => 150, "初期MP" => 30}, {"名前" => "音助", "属性" => "波", "最大MP" => 100, "初期MP" => 80} ]
変数に代入して、個別にアクセスしてみる。irbで以下を実行してみよ。
irb chara = [ {"名前" => "ドナポン", "属性" => "甘", "最大MP" => 250, "初期MP" => 20}, {"名前" => "ラジャイン", "属性" => "土", "最大MP" => 450, "初期MP" => 2}, {"名前" => "リッタン", "属性" => "沼", "最大MP" => 150, "初期MP" => 30}, {"名前" => "音助", "属性" => "波", "最大MP" => 100, "初期MP" => 80} ] chara => [{"名前"=>"ドナポン", "属性"=>"甘", "最大MP"=>250, "初期MP"=>20}, {"名前"=>"ラジャイン", "属性"=>"土", "最大MP"=>450, "初期MP"=>2}, {"名前"=>"リッタン", "属性"=>"沼", "最大MP"=>150, "初期MP"=>30}, {"名前"=>"音助", "属性"=>"波", "最大MP"=>100, "初期MP"=>80}] # 先頭要素[0]を取り出す chara[0] => {"名前"=>"ドナポン", "属性"=>"甘", "最大MP"=>250, "初期MP"=>20} # 4番目[3]を取り出す chara[3] => {"名前"=>"音助", "属性"=>"波", "最大MP"=>100, "初期MP"=>80} # 4番目[3]の名前を取り出す chara[3]["名前"] =>"音助" # 4番目[3]の初期MPを上書きして90に更新する chara[3]["初期MP"]=90 => 90 chara[3] => {"名前"=>"音助", "属性"=>"波", "最大MP"=>100, "初期MP"=>90}
この(chara)配列に、新たなキャラクタのハッシュ値を追加する
例を示す。charaは配列なので要素として追加する。
chara << {"名前"=>"ハテナ", "属性"=>"謎", "最大MP"=>400, "初期MP"=>0} => [{"名前"=>"ドナポン", "属性"=>"甘", "最大MP"=>250, "初期MP"=>20}, {"名前"=>"ラジャイン", "属性"=>"土", "最大MP"=>450, "初期MP"=>2}, {"名前"=>"リッタン", "属性"=>"沼", "最大MP"=>150, "初期MP"=>30}, {"名前"=>"音助", "属性"=>"波", "最大MP"=>100, "初期MP"=>90}, {"名前"=>"ハテナ", "属性"=>"謎", "最大MP"=>400, "初期MP"=>0}]
5個目(第4)要素が増えた。
ある八百屋にあった3品目の単価リスト:
りんご:150 みかん:30 いちご:20
をハッシュ形式で表現し、それを変数yaoyaに
     代入する文を書け(答は何通りもある)。
yaoya変数に「梨:120」を表現する値を代入する
     文を書け(答は何通りもある)。
 東北6県の各県について「都道府県名」「県庁所在地」「人口」を
     キーとするハッシュを作り、それらを6要素の配列としたものを変数
     tohoku に代入する文を書け。