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.name や person.age のように扱う
自己紹介文を返すメソッドを Person の中に持たせる
といった、「オブジェクト指向」の入り口に入っていきます。
