ハッシュの利用

ハッシュを利用するためには、色々な構造のデータをハッシュ形式にうまく 保存していく方法と、あとでハッシュから key と value を取り出 すための方法に慣れておく必要がある。いくつかの題材を 見ながら、ハッシュを効率的に利用するメソッドとその使い方を覚えていこう。

少し複雑なハッシュ

成績処理のデータで、国語以外の点を追加しよう。データは以下のとおりとする。

score2.txt

山田太郎        50  40
中町太郎        90  70
飯森花子        91  90
鶴岡一人        60  50
酒田三吉        52  80
三川一二三      12  75

これをハッシュ構造に入れようとすると今までどおりではうまくいかない。 ハッシュ構造を持つ変数が point だとすると、key「山田太郎」の、 valueは「50と40」という複合値になる。

ハッシュの value には数値だけでなく、配列や、(さらに)ハッシュなども 定義できるので、

point["山田太郎"] = [50, 40]

のような代入も行なえる。これを利用するとプログラムは以下のようになる。

score-hash2.rb

#!/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(5, 0)

とすると、

[0, 0, 0, 0, 0]

という配列が作成される。初期値を指定せず、

Array.new(4)

などとした場合は、

[nil, nil, nil, nil]

のように、各要素の初期値が nil の配列が作成される。 ハッシュと違い、配列には存在しない範囲の添字の値を参照したときの デフォルト値は指定できない。範囲外の添字を指定したときの値は nil となる。


本日の目次