ハッシュを利用するためには、色々な構造のデータをハッシュ形式にうまく 保存していく方法と、あとでハッシュから key と value を取り出 すための方法に慣れておく必要がある。いくつかの題材を 見ながら、ハッシュを効率的に利用するメソッドとその使い方を覚えていこう。
成績処理のデータで、国語以外の点を追加しよう。データは以下のとおりとする。
山田太郎 50 40 中町太郎 90 70 飯森花子 91 90 鶴岡一人 60 50 酒田三吉 52 80 三川一二三 12 75
これをハッシュ構造に入れようとすると今までどおりではうまくいかない。 ハッシュ構造を持つ変数が point だとすると、key「山田太郎」の、 valueは「50と40」という複合値になる。
ハッシュの value には数値だけでなく、配列や、(さらに)ハッシュなども 定義できるので、
point["山田太郎"] = [50, 40]
のような代入も行なえる。これを利用するとプログラムは以下のようになる。
#!/usr/koeki/bin/ruby # coding: utf-8 point = Hash.new sum = Array.new(2,0) # sumは配列にする。要素2個、デフォルト値は0 ave = Array.new(2,0) # aveも配列にする。要素2個、デフォルト値は0 while yline = gets if /(\S+)\s+(\d+)\s+(\d+)/ =~ yline # 1個目の() (\S+)→氏名が入る # 2個目の() (\d+)→国語の得点が入る # 3個目の() (\d+)→数学の得点が入る point[$1] = [$2.to_i, $3.to_i] # 配列を代入 sum[0] += point[$1][0] # 国語 sum[1] += point[$1][1] # 数学 end end ave[0] = sum[0].to_f/point.length # 国語の平均点 ave[1] = sum[1].to_f/point.length # 数学の平均点 print "--氏名--------------+-国語-+-平均との差--+-数学-+-平均との差--\n" for student, pts in point # pts には、[国語の点, 数学の点] という配列が入っている kokugo = pts[0] # ptsの第0要素が国語の点 math = pts[1] # ptsの第1要素が数学の点 printf("%-20s %5d %5.1f %5d %5.1f\n", student, kokugo, kokugo-ave[0], math, math-ave[1]) end puts "-"*62 printf("%-20s %5.1f%s%5.1f\n", "平均点", ave[0], " "*15, ave[1])
ハッシュの初期宣言として
x = Hash.new
のように、デフォルト値を指定しなかった場合、存在しない key の
value を参照するとnil
が返る。
x["hoge"] # "hoge" というkeyは未登録
=> nil
ところがもし、
x = Hash.new(0)
のように、デフォルト値を指定した場合、存在しない key の value を参照すると、指定した値が返る。
x["hero"] # "hero" というkeyは未登録
=> 0
初期宣言として、Hash.new()
を利用した場合は
デフォルト値が指定できるが、{ }
を利用して
ハッシュの初期値を代入した場合は、デフォルト値は nil
となる。つまり、
x = { "りんご" => "apple", "みかん" => "orange", "いちご" => "strawberry" }
と初期値代入した場合、未登録keyのvalueを参照するとnil
となる。
x["梨"] # "梨" というkeyは未登録
=> nil
このようなときに、あとからデフォルト値を設定するには ハッシュに属する
メソッドである default=
を利用する。
x.default="わかりませーん"
すると、以下のようになる。
x["梨"] # "梨" というkeyは未登録 => "わかりませーん" x["りんご"] # "りんご" というkeyは登録されている => "apple"
配列の場合は、決まった長さ(要素数)のものを、決められた値で
埋めつくした初期配列を作ることができる。これには Array.new
を利用する。
Array.new(長さ)
Array.new(長さ, 初期値)
指定した 長さ の要素数を持つ配列を作成する。 初期値 を指定した場合には、全ての要素に その 初期値 を代入する。
たとえば、
Array.new(5, 0)
とすると、
[0, 0, 0, 0, 0]
という配列が作成される。初期値を指定せず、
Array.new(4)
などとした場合は、
[nil, nil, nil, nil]
のように、各要素の初期値が nil
の配列が作成される。
ハッシュと違い、配列には存在しない範囲の添字の値を参照したときの
デフォルト値は指定できない。範囲外の添字を指定したときの値は
nil
となる。