Ruby | 2週間で身につく、アプリを作りながら学ぶRubyの基本 - 4日目

Ruby Ruby
スポンサーリンク

4日目のゴールとテーマ

4日目のテーマは「1人分の情報を“ひとまとまりのデータ”として扱う」です。
3日目までは「自己紹介文=ただの長い文字列」として扱っていました。

今日はそこから一歩進めて、

1人分の情報を「名前」「年齢」「趣味」などの項目ごとに持つ
その“まとまり”をハッシュで表現する
配列 × ハッシュで「名簿っぽいデータ構造」を作る

ここまで行けると、「アプリが扱うデータの形」を意識できるようになります。


「ただの文字列」だと何がつらいのか

自己紹介文だけだと、あとから扱いにくい

3日目までの自己紹介アプリでは、1人分の情報をこう扱っていました。

intro = ""
intro += "はじめまして、#{name}です。\n"
intro += "年齢は#{age}歳です。#{age_comment}\n"
intro += "好きなことは#{hobby}です。\n"
intro += "よろしくお願いします!\n"
Ruby

そして、配列にはこの intro(長い文字列)を入れていました。

introductions << intro
Ruby

これでも「表示するだけ」なら十分です。
でも、例えば次のようなことをしたくなったらどうでしょう。

名前だけを一覧表示したい
20歳未満の人だけをピックアップしたい
趣味が「ゲーム」の人だけを探したい

自己紹介文はただの文字列なので、
そこから名前や年齢だけを取り出すのはとても大変です。

ここで必要になるのが、「項目ごとにデータを持つ」という発想です。


ハッシュとは何かをイメージでつかむ

「名前つきの引き出しが並んだ箱」

配列は「0番、1番、2番…」という番号でアクセスしました。
ハッシュは、「キー」と呼ばれる“名前”でアクセスします。

イメージとしては、

名前というラベルがついた引き出しがいくつも並んでいて
「:name の引き出し」「:age の引き出し」「:hobby の引き出し」
という感じで、中身を出し入れできる

という箱です。

Rubyのハッシュは、こう書きます。

person = {
  name: "たろう",
  age: 25,
  hobby: "ゲーム"
}
Ruby

この person は、「1人分の情報」を表すデータです。


ハッシュの基本操作

値を取り出す

ハッシュから値を取り出すときは、キーを指定します。

puts person[:name]   # たろう
puts person[:age]    # 25
puts person[:hobby]  # ゲーム
Ruby

ここでのポイントは、キーに :name のような「シンボル」を使っていることです。
シンボルは、: から始まる「名前だけの値」で、ハッシュのキーによく使われます。

値を変更する・追加する

ハッシュの中身は、あとから変更したり追加したりできます。

person[:age] = 26
person[:comment] = "よろしくお願いします!"
Ruby

これで、age は 26 に更新され、comment という新しい項目が増えます。


1人分の自己紹介情報をハッシュで表現する

入力からハッシュを作るメソッドにする

今までの build_introduction は「自己紹介文(文字列)」を返していました。
これを「1人分の情報をハッシュで返す」形に変えてみます。

def build_age_comment(age)
  if age <= 0
    "年齢はひみつなんですね。"
  elsif age < 20
    "とても若いですね!"
  elsif age < 40
    "働き盛りの世代ですね。"
  else
    "人生経験が豊富そうですね。"
  end
end

def build_person
  puts "あなたの名前を教えてください:"
  name = gets.chomp

  puts "あなたの年齢を教えてください:"
  age_text = gets.chomp
  age = age_text.to_i

  puts "あなたの好きなこと(趣味)を教えてください:"
  hobby = gets.chomp

  age_comment = build_age_comment(age)

  person = {
    name: name,
    age: age,
    hobby: hobby,
    age_comment: age_comment
  }

  return person
end
Ruby

ここでの重要ポイントを丁寧に見ていきます。

入力はこれまでと同じく、名前・年齢・趣味を聞いている
年齢コメントは build_age_comment に任せている
最後に person = { ... } でハッシュを作っている
キーは name:, age:, hobby:, age_comment: のように書いている
戻り値は「1人分の情報を持ったハッシュ」になっている

これで、「1人分の自己紹介情報」を
「意味のある項目ごとのデータ」として扱えるようになりました。


配列 × ハッシュで「名簿データ」を作る

複数人分のハッシュを配列にためる

今度は、build_person を使って複数人分のデータを集めます。

puts "何人分の情報を登録しますか?"
count_text = gets.chomp
count = count_text.to_i

people = []

i = 1
while i <= count
  puts "========================"
  puts "#{i}人目の情報を入力します。"

  person = build_person

  people << person

  i += 1
end
Ruby

ここでの流れはこうです。

人数を聞いて count に入れる
空の配列 people を用意する
人数分だけループして、毎回 build_person で1人分のハッシュを作る
作ったハッシュを people に追加していく

ループが終わったとき、people は

1人目のハッシュ
2人目のハッシュ

という「ハッシュの配列」になっています。

つまり、「名簿データ」ができあがった状態です。


ハッシュの配列から自己紹介文を作って表示する

1人分のハッシュから自己紹介文を作るメソッド

今度は、「ハッシュから自己紹介文を作る」メソッドを書きます。

def build_introduction_from_person(person)
  name = person[:name]
  age = person[:age]
  hobby = person[:hobby]
  age_comment = person[:age_comment]

  intro = ""
  intro += "はじめまして、#{name}です。\n"
  intro += "年齢は#{age}歳です。#{age_comment}\n"
  intro += "好きなことは#{hobby}です。\n"
  intro += "よろしくお願いします!\n"

  return intro
end
Ruby

ここでのポイントは、
「ハッシュから必要な情報を取り出して、文章を組み立てている」ことです。

名前が欲しければ person[:name]
年齢が欲しければ person[:age]

というように、項目ごとにアクセスできます。

全員分の自己紹介を一覧表示する

people(ハッシュの配列)を each で回して、
1人ずつ自己紹介文を表示してみます。

puts "========================"
puts "全員分の自己紹介を表示します。"

people.each_with_index do |person, idx|
  puts "------------------------"
  puts "#{idx + 1}人目の自己紹介:"

  intro_text = build_introduction_from_person(person)
  puts intro_text
end
Ruby

ここでの流れはこうです。

each_with_index で people を先頭から順に取り出す
person には1人分のハッシュが入る
build_introduction_from_person(person) で自己紹介文を作る
それを puts で表示する

3日目までは「配列の中身が長い文字列」でしたが、
4日目では「配列の中身がハッシュ(構造化されたデータ)」になっています。


ハッシュだからこそできること

名前だけの一覧を表示する

例えば、「登録された人の名前だけ一覧で見たい」とします。
ハッシュなら、こう書けます。

puts "========================"
puts "登録されている名前の一覧:"

people.each_with_index do |person, idx|
  puts "#{idx + 1}人目: #{person[:name]}"
end
Ruby

自己紹介文から名前だけを抜き出すのは大変ですが、
ハッシュなら person[:name] で一発です。

20歳未満の人だけを表示する

年齢でフィルタするのも簡単です。

puts "========================"
puts "20歳未満の人の自己紹介:"

people.each do |person|
  if person[:age] < 20
    intro_text = build_introduction_from_person(person)
    puts "------------------------"
    puts intro_text
  end
end
Ruby

ここでのポイントは、
「条件に合う人だけ自己紹介を表示している」ことです。

ハッシュで項目ごとにデータを持っているからこそ、
こういう「条件付きの表示」が自然に書けます。


4日目の全体コードイメージ

ここまでの流れをまとめると、アプリ全体はこんな構造になります。

年齢コメントを決めるメソッド(build_age_comment)
1人分の情報をハッシュとして作るメソッド(build_person)
ハッシュから自己紹介文を作るメソッド(build_introduction_from_person)
人数を聞いて people(ハッシュの配列)を作る
全員分の自己紹介を表示する
名前だけの一覧を表示する
20歳未満の人だけを表示する

コードとしては少し長くなるので、ここでは構造のイメージを大事にしてください。
「配列の中にハッシュが入っている」という形が見えていればOKです。


4日目のまとめ

今日のキーワードを整理します。

ハッシュ
{ name: "たろう", age: 25 } のように、
キーと値のペアをまとめて持つデータ構造。
「名前つきの引き出しが並んだ箱」のイメージ。

シンボルキー
:name:age のように、: から始まる名前。
ハッシュのキーとしてよく使われる。

配列 × ハッシュ
「people = []」で配列を用意し、
「people << person」でハッシュを追加していく。
結果として「ハッシュの配列=名簿データ」ができる。

構造化されたデータ
自己紹介文をただの文字列として持つのではなく、
「名前」「年齢」「趣味」「コメント」を別々の項目として持つことで、
あとから「名前だけ」「20歳未満だけ」などの操作がしやすくなる。


次回(5日目)への予告

5日目は、今日の「ハッシュで表現した1人分の情報」を、
Rubyらしく「クラス」として表現する方向に進みます。

Person というクラスを作って、
person.nameperson.age のように扱う
自己紹介文を返すメソッドを Person の中に持たせる

といった、「オブジェクト指向」の入り口に入っていきます。

タイトルとURLをコピーしました