【Ruby】レッスン4-08:ハッシュでキーと値のデータ管理を理解しよう

一つ前のページではfilterメソッドについて学習しました。
今回は ハッシュ について見ていきましょう。
Lesson1:基礎文法編
Lesson2:制御構造編
Lesson3:メソッド編
Lesson4:コレクション編
・Lesson4-1:配列の基本を理解しよう
・Lesson4-2:配列を操作しよう
・Lesson4-3:配列を調査しよう
・Lesson4-4:配列を並び替えよう
・Lesson4-5:eachメソッドを理解しよう
・Lesson4-6:mapメソッドを理解しよう
・Lesson4-7:filterメソッドを理解しよう
・Lesson4-8:ハッシュを理解しよう ◁今回はココ
・確認問題4-☆1:ナインゲームを作ろう
・確認問題4-☆2:アラビア数字をローマ数字に変換しよう
・確認問題4-☆3:トランプをランダムに配ろう
Lesson5:オブジェクト指向編
Rubyのハッシュ入門|キーと値で柔軟なデータ構造を作ろう

Rubyのハッシュはデータを「キー」と「値」のペアで管理するデータ構造です。
配列がインデックス(番号)を使って値を管理するのに対し、ハッシュは任意のキーを使って値を参照できます。
そのためデータの意味をわかりやすく管理したい場合に便利です。
例えばユーザーの情報を管理する場合、名前や年齢などのデータに適切なラベル(キー)を付けて保存できます。
ハッシュの基本構文と定義方法
ハッシュは中括弧 {}
を使って定義します。
キーと値はコロン :
で区切り、ペアごとにカンマ ,
で区切ります。以下は基本的なハッシュの例です。
user = { name: "John", age: 25, city: "Tokyo" }
ここでname
、age
、city
がキーで、"John"
、25
、"Tokyo"
がそれぞれの値です。
このように、キーにはシンボル(例::name
)を使用することが一般的です。シンボルは軽量で高速に動作します。
数値や文字列をキーに使用する場合は以下のように、矢印のような記号を作って記述します。
custom_hash = { 1 => "One", "two" => 2, }
データの追加・更新・削除方法
ハッシュにデータを追加したり更新したりするのは簡単です。
以下にいくつかの操作例を示します。
値の取得
キーを指定して値を取得します。
user = { name: "John", age: 25 } puts user[:name] # 結果: John
値の追加と更新
新しいキーと値を追加するか、既存のキーを更新できます。
user[:city] = "Tokyo" # 新しいキーを追加 user[:age] = 30 # 既存のキーを更新
値の削除
delete
メソッドを使うと特定のキーと値を削除できます。
user.delete(:age)
よく使うハッシュメソッド一覧
Rubyのハッシュには多くの便利なメソッドが用意されています。
ここでは主要なメソッドを紹介します。
length
と size
ハッシュの要素数を取得します。どちらも同じ結果を返します。
user = { name: "John", age: 25 } puts user.length # 結果: 2 puts user.size # 結果: 2
keys
と values
キーだけ、または値だけを取得します。
user = { name: "John", age: 25 } puts user.keys # 結果: [:name, :age] puts user.values # 結果: ["John", 25]
key?
と value?
指定したキーや値が存在するか確認します。
user = { name: "John", age: 25 } puts user.key?(:name) # 結果: true puts user.value?(30) # 結果: false
Rubyハッシュのまとめと活用ポイント
Rubyのハッシュはデータを整理して管理するのに非常に便利なデータ構造です。
キーと値のペアを使うことで、コードがより読みやすく意味のあるものになります。
これを活用してアプリケーションのデータ構造を効率的に構築しましょう!
練習問題|ハッシュを使って学生の成績を集計しよう

ハッシュを使った成績カウントの実践課題
学生の成績データをハッシュを使って管理し、それぞれの成績ごとに何人の学生がいるかをカウントするプログラムを作成しましょう。
このプログラムでは、複数の学生の成績を集計し、結果を表示します。
成績データはハッシュとして以下のように与えられます。
students = { "田中" => "A", "佐藤" => "B", "鈴木" => "A", "高橋" => "C", "伊藤" => "B", "渡辺" => "A" }
以下の要件に従ってコードを完成させてください。
- 学生の名前と成績を管理するハッシュ
students
を定義し、複数の学生の名前と成績を格納すること。 - ハッシュ
students
を使って、それぞれの成績をカウントし、grade_count
ハッシュに格納すること。 each
メソッドを使って、students
ハッシュの各要素を繰り返し処理すること。- 最後に、
grade_count
ハッシュに基づいて、それぞれの成績の学生数を表示すること。
ただし、以下のような実行結果となること。
成績A: 3人 成績B: 2人 成績C: 1人
【ヒント】自力で解くのが難しい人へ
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
- ヒント1【コードの構成を見る】
-
正解のコードは上から順に以下のような構成となっています。
(※下記の□はコード内のインデントを表しています)1:studentsハッシュを初期化し、各学生の名前と成績を格納
2:grade_countハッシュを初期化し、各成績のカウントを保存する準備
3:studentsハッシュの各要素に対して繰り返し処理を実行
□ name変数にキー(名前)、grade変数に値(成績)を代入
□ if文でgrade_countハッシュにgradeキーが存在するかを判定
□ □ gradeキーが存在する場合、値を1増加
□ □ gradeキーが存在しない場合、新たにキーを作成し値を1に設定
4:grade_countハッシュの各要素に対して繰り返し処理を実行
□ grade変数にキー(成績)、count変数に値(人数)を代入
□ 成績と人数を文字列に整形して出力
- ヒント2【穴埋め問題にする】
-
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
# 学生の成績データ students = { "田中" => "A", "佐藤" => "B", "鈴木" => "A", "高橋" => "C", "伊藤" => "B", "渡辺" => "A" } # 各成績のカウントを格納するためのハッシュ grade_count = {} # ハッシュ内の各成績をカウント students.each do |name, grade| =begin 【穴埋め問題1】 ここに、すでにその成績がカウントされているかを確認し、カウントを増やすか新しいカウントを開始するコードを書いてください。 =end end # 各成績の学生の数を表示 grade_count.each do |grade, count| =begin 【穴埋め問題2】 ここに、成績とそれに対応する学生の人数を表示するコードを書いてください。 =end end
このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。
この問題の解答例と解説
この問題の正解コードとその解説は以下の通りです。
クリックして開いて確認してください。
- 正解コード
-
# 学生の成績データ students = { "田中" => "A", "佐藤" => "B", "鈴木" => "A", "高橋" => "C", "伊藤" => "B", "渡辺" => "A" } # 各成績のカウントを格納するためのハッシュ grade_count = {} # ハッシュ内の各成績をカウント students.each do |name, grade| if grade_count[grade] # すでにその成績がカウントされている場合は、カウントを増やす grade_count[grade] += 1 else # 初めて出現した成績の場合は、カウントを1にする grade_count[grade] = 1 end end # 各成績の学生の数を表示 grade_count.each do |grade, count| puts "成績#{grade}: #{count}人" end
- 正解コードの解説
-
コードをブロックごとに分割して解説します。
ハッシュの定義
students = { "田中" => "A", "佐藤" => "B", "鈴木" => "A", "高橋" => "C", "伊藤" => "B", "渡辺" => "A" }
ここでは
students
という名前のハッシュを定義しています。ハッシュでは、キーと値をセットで管理します。この場合キーは学生の名前で、値はその学生の成績です。
空のハッシュの作成
grade_count = {}
grade_count
という空のハッシュを定義しています。このハッシュは各成績(A, B, Cなど)が何回出現したかをカウントするために使います。
ハッシュの要素を繰り返し処理
students.each do |name, grade| if grade_count[grade] grade_count[grade] += 1 else grade_count[grade] = 1 end end
この部分では
students
ハッシュをeach
メソッドで繰り返し処理しています。name
には学生の名前、grade
には成績が格納され、それぞれの成績をgrade_count
ハッシュでカウントします。if
文: ここですでにgrade_count
にその成績が登録されているかをチェックしています。もし成績がすでに存在していればカウントを1増やし、存在しない場合は初めてその成績が出現したとしてカウントを1に設定します。
結果の表示
grade_count.each do |grade, count| puts "成績#{grade}: #{count}人" end
最後に
grade_count
ハッシュを使って、それぞれの成績の学生数を表示しています。each
メソッドを使って、キー(成績)と値(人数)を一つずつ取り出し、puts
で表示しています。
まとめ
このプログラムでは、ハッシュ を使って成績データを効率的に集計しています。
ハッシュは、複数のデータをキーと値で管理し、特定のキーに関連する値を簡単に操作することができる非常に便利なデータ構造です。
FAQ|Rubyのハッシュの使い方と疑問解消
- Q1. Rubyでハッシュのキーにはシンボルと文字列のどちらを使うべきですか?
-
処理速度やメモリ効率を重視する場合は、シンボル(例:
:name
)の使用が推奨されます。シンボルは一度生成されると再利用されるため、文字列よりも軽量で高速です。ただし、外部から動的にキーが渡る場合などには文字列を使う場面もあります。
- Q2. Hash#key? と Hash#has_key? の違いはありますか?
-
key?
はhas_key?
のエイリアスで、機能的な違いはありません。ただし、key?
の方が短くモダンな書き方とされるため、可読性を意識してkey?
の使用が一般的です。
- Q3. Rubyのハッシュにおいて順序は保持されますか?
-
Ruby 1.9以降、ハッシュは定義された順序を保持するようになりました。これは、
each
などでキーを取り出す際に順序が維持されることを意味し、意図した順番でデータを扱えるため便利です。