今日は二人にRubyのハッシュを覚えてもらいますよ
ハッシュ……知らないねぇ。 まったくもって初耳です
キャニット先生! ハッシュって何ですか?
まずはそこからですよね。 実は前回の講義の配列ともつながっている話なので、できれば配列を軽く復習してから講義を聞いてください。 では、いきましょう
前回の「配列」の復習をしたい方は、こちらからできます。
Rubyの学習:ハッシュって何?
簡単に説明すると……ハッシュとは、Rubyの配列の添え字を文字列にしたものです
さっぱりわからん
ですよね(笑) Rubyの難しい部分の1つなので、詳しく解説しますね
具体例
ゲームの話で例えます。
ゲーム内で名前からスコアを確認したい。そんな状況は頻繁にあります。そのプログラムを二次元配列を使って書くと以下のようになります。
name = [[“田中一郎”, 10032], [“鈴木太郎”, 2399], [“中村次郎”, 48888]]
田中さんが10032点と……ここまでは何となくわかります
はい。 この書き方でも問題はないのですが、この後の処理が少し複雑になってしまうんですね。 簡単に処理できるように、本当は下のように書きたいんですよ
name[“田中一郎”] = 10032
name[“鈴木太郎”] = 2399
name[“中村次郎”] = 48888
しかし、配列ではいきなり添え字に文字列を取ることはできません。文字列を使うためには、ハッシュというデータ構造を使う必要があります。
ここでハッシュの出番なのかー
ハッシュを使ってコードを書いてみよう
というわけで、ハッシュを使ってコードを書いてみます
name = {“田中一郎” => 10032, “鈴木太郎” => 2399, “中村次郎” => 48888}
p name[“鈴木太郎”]
p name[“山本三郎”]
これで鈴木太郎の点数が出るようになりました。
ちなみに一度データを入力したハッシュは、自由に新しいデータを追加できます。また、配列の添え字に当たる”田中一郎”の部分をキー(key)と呼びます。
鈴木さんの点数は出ましたけど……最初のnameのところに山本さんはいませんよね。 いない人の点数はどうなるんですか?
存在しないキーを指定するとnilが返ってきます。山本さんはnameのところに名前がないので、点数は出ませんね
キーは文字列でなくても(つまり整数でも)構いません。
また、print, puts, pでほぼ同じ結果が返ってきます。また、ハッシュの内容の方(この場合は2399とかの数字部分)を値(value)と呼びます。
ハッシュの大きさは、配列と同じように、size, lengthで得られます。
name.length
name.size
ハッシュの特徴
もっと詳しくハッシュを学ぶ前に、少しハッシュの特徴に触れておきましょうか。ハッシュがどういうものかを知ると、学びやすいかもしれません
まず知って欲しいのはRubyの特徴です。Rubyはキーを探しに行くのではなく、計算によって値を得ます。
だから、計算に時間がかかると結果が反映されるのが遅くなってしまうのですが……ハッシュは非常に高速なのでデータの量が増えても探索の時間が増えることはありません。
専門的な話をすると、ハッシュ関数というものを使っているので、高速で動かすことができるんですよ
ただ、大量にメモリを消費する欠点がハッシュにはあります。 配列の数倍から数十倍のメモリを使うので、20世紀の時代でのハッシュはあまり実用的ではありませんでした。メモリが非常に高価だったからです。
なるほど。 PCが進化したから、ハッシュが日常的に使えるようになったんですね
ハッシュのデータには順番がない
ハッシュのもう一つの大きな特徴は、ハッシュにはデータの順番がないことです。
書いた順番、追加した順番に表示されますが、順番は保証されていません。
どうしても順番通りに使いたいのなら、ハッシュではなく配列を使います。あるいは、sortして使う方法もあります。sortに関しては後述しますね。
順番が保証されていないと不安になるかもしれませんが、世の中のデータには順番が重要でないものも結構多いです。
たとえば、日本の都道府県は国が決めた番号もありますが、データとして格納するときは順番は重要ではないのが分かるかと思います。
ハッシュの繰り返し:3つの方法
ハッシュは繰り返すこともできます。 繰り返したいときは、eachメソッドを使います。 eachは配列のときに使いましたね。ここでは、3種類の繰り返し方を紹介します
- キーのみ
- 値のみ
- キーと値の対
ハッシュの繰り返し①:キーのみ繰り返す
まずは、キーだけを繰り返す方法です。以下のようにコードを書くとnameのすべてのキーを取り出すことができます。
name = {“田中一郎” => 10032, “鈴木太郎” => 2399, “中村次郎” => 48888}
name.each_key{|key|
print(“key = ” + key + “\n”)
}
name.each_key{|key|
ハッシュの繰り返し②:値のみ繰り返す
続いては値だけを繰り返す方法です。以下のようにコードを書くとnameのすべての値を取り出すことができます。
name = {“田中一郎” => 10032, “鈴木太郎” => 2399, “中村次郎” => 48888}
name.each_value{|value|
print(“value = ” + value + “\n”)
}
name.each_value{|value|
ハッシュの繰り返し③:キーと値の対を繰り返す
最後がキーと値を対にして取り出すやり方です。
name = {“田中一郎” => 10032, “鈴木太郎” => 2399, “中村次郎” => 48888}
name.each{|key, value|
print(key,” => “,value ,”\n”)
}
単に、
print name
と書くとまとめてハッシュの内容が出力されますが、each文を使うとひとつづつハッシュの内容が取り出せます。
なんかすでにチンプンカンプンなんですけど
複雑なコードに見えるかもしれませんが、今紹介した3つはほとんど一緒ですよ。だから1つ覚えてしまえば、応用が効くのでそんなに難しくないです
本当だ。 よくみたら、法則性があるので結構シンプルですね
ハッシュの応用:削除・結合・並び替え(sort)
では、この調子でハッシュの応用も覚えておきましょう
削除
ハッシュのキーと値の対をまるごと削除したいときは、deleteを使います。
name = {“田中一郎” => 10032, “鈴木太郎” => 2399, “中村次郎” => 48888}
p name
name.delete(“鈴木太郎”)
p name
結合
二つのハッシュを結合して、一つのハッシュにしたいときはmergeを使います。
name1 = {“田中一郎” => 10032, “鈴木太郎” => 2399}
name2 = {“中村次郎” => 48888}
name3 = name1.merge(name2)
p name1
p name2
p name3
並び変え(sort)
ハッシュのとてもありがたい機能が並び変え(sort)です。
name = {“田中一郎” => 10032, “鈴木太郎” => 2399, “中村次郎” => 48888}
p name.sort
p name
値の大きい順に並び変えてくれます。sortは非破壊的(元のハッシュに上書きしない)ので、sort後に、
p name
とすると、元のハッシュが表示されます。sortされた結果を使いたいときは、以下のように別のハッシュに保存をします。
name1 = name.sort
その他のハッシュの機能
最後にハッシュでできるさまざまなことを、まとめて紹介しておきます。 全部を覚える必要はありませんよ。 でも「ハッシュでは、こういうこともできる」と頭の片隅に入れておいてください
sortは何もしないと降順(値が大きい順)で動きますが、昇順(値が小さい順)にしたい場合はreverseと組み合わせます。また、sortなどの返り値は二次元配列のことがあるのですが、これをハッシュに戻すにはto_hを用います。
Rubyの学習:ハッシュまとめ
はい。 というわけで、ハッシュについての講義はここまでにしましょうか
最初は複雑に感じましたけど、よく見たらそうでもなかったので安心しました
実際に使う場面がこないと、よくわからないなぁ
そうなんですよね。プログラミングは実際に使う場面がきて、初めて学習が役立ちます。 それまでは「ハッシュでは、こういうことができる」と覚えておくだけでも十分ですよ
おっけー おっけー じゃあこの調子で次行ってみよー