Rubyに限らず、開発言語の世界では配列の要素番号はゼロから始まるのが一般的です。
配列は要素番号は数値のみです。しかし要素番号が数値ではなく何らかの意味を持つ値を使えると便利です。そうなると、「キー」とそれに対する「値」のペアでデータを管理することができます。
例えば、会員制サイトを考えましょう。
英数字が混在したユーザーコードがキーとなり、ユーザー名が値となります。このように、配列のようで配列でない、要素番号は数値以外も使えるというデータ構造をハッシュといいます。
他言語では連想配列とも呼ばれます。
本記事では、Rubyにおけるハッシュと、キーとしてよく使われるシンボルを解説します。
ハッシュとは
ハッシュとは何か
前述の通り、キーと値を組み合わせて保持するデータ構造です。配列は開始番号をゼロとした要素番号でしか要素を指定できません。
ハッシュはそうではなく、◯◯のときは××、といったキーに対する値という形で値を管理できます。
ユーザーコード(文字列)とユーザー名(文字列)の組み合わせで実現してみましょう。
user = {"user1" => "ユーザー1", "user2" => "ユーザー2"} p user
[実行結果]
{"user1"=>"ユーザー1", "user2"=>"ユーザー2"}
ユーザーコードとユーザー名が紐付いているのがわかります。
ハッシュの操作
キーをもとに値を取り出しましょう。配列と同じような形式で記述します。
user = {"user1" => "ユーザー1", "user2" => "ユーザー2"} puts user["user1"]
[実行結果]
ユーザー1
user1というキーに紐づく名前が取り出せました。
書き換えるときもキーを指定すればよく、「user[“user1”]=”変更する文字列”」とすればOKです。
シンボルを使ったハッシュ
シンボルとは何か
Rubyではキーの値には文字列よりシンボルが使われることが多いです。ここで、シンボルとは何かを解説します。
シンボルとは、文字列を格納するよりも、何らかの名前を振るときによく使われるオブジェクトです。
他言語の経験がある方は、これがまた理解が難しい!なかなかピンとこないでしょう。
分かりづらければ、シンボルとはハッシュのキーのような「名前的」に使う場面で頻繁に使用されると理解してください。
先ほどの例では、ハッシュのキーに文字列を使いました。もちろんそれでもよいのですが、Rubyにはこのような名前的使い方をする場面ではシンボルを使います。
シンボルを使ったハッシュの作り方
では、シンボルを使ってハッシュを作ってみましょう。
user = {:user1 => "ユーザー1", :user2 => "ユーザー2"} puts user
[実行結果]
{:user1=>"ユーザー1", :user2=>"ユーザー2"}
取り出すときも、キーが文字列の場合と同じです。
hash = {:user1 => "ユーザー1", :user2 => "ユーザー2"} puts hash[:user1]
[実行結果]
ユーザー1
:user1に紐づいたユーザー1を取得できました。
シンボルと文字列のちがい
文字列でできることは、だいたいシンボルでもできます。違うのは以下の点です。
シンボルは、コード上では文字列のように見えていますが、内部的には数値として処理されます。よって、検索するときは文字列と比べて速度的に有利です。
以下、Rubyのマニュアルからの抜粋です。
シンボルを表すクラス。シンボルは任意の文字列と一対一に対応するオブジェクトです。
文字列の代わりに用いることもできますが、必ずしも文字列と同じ振る舞いをするわけではありません。
シンボルは、immutable(イミュータブル:変更不可能)です。一度宣言してしまうと内容を変更できません。
興味のある方は、前述のマニュアルを読んでみてください。
シンボルを使った場合の簡単な表記方法
シンボルを使ったハッシュは、もっと簡単に書くことが可能です。
コロンをシンボル名の後ろに持ってきて、=>を省くことができます。
hash = {user1: "ユーザー1", user2: "ユーザー2"} puts hash
[実行結果]
{:user1=>"ユーザー1", :user2=>"ユーザー2"}
開発現場ではこちらの形式の方がよく使われます。
この書き方だと、=>が不要です。タイプ数がだいぶ減るので効率的ですよね。
シンボルを文字列に変換する to_s
シンボルと文字列は全く別のものです。よって、以下のようなプログラムを実行すると、結果が返ってきません。
user = {"user1" => "ユーザー1", "user2" => "ユーザー2"} puts user[:user1]
キーが文字列なのに、ハッシュでキーを検索したので当然ですね。
ハッシュを文字列に変換するメソッドがあります。それがto_sです。先ほどのプログラムを以下のように書き換えると、検索結果が返ります。
user = {"user1" => "ユーザー1", "user2" => "ユーザー2"} puts user[:user1.to_s]
[実行結果]
ユーザー1
ハッシュを文字列に変換したおかげで、キーを見つけることができて結果が表示されました。
ハッシュのキーを検索する
求めるキーがハッシュに存在しているかを調べるには、key?を使います。ただし、同じ動きをするものがほかにもあります。
hash.key?
hash.has_key?
hash.include?
hash.member?
どれも同じ動きをします。よって、シンプルに書きたいのでkey?、「持っている」の意味を強調したいのでhas_key?、ハッシュ以外でも良く使うので統一性をもたせるためにinclude?、などと自由に使い分けてください。
hash = {user1: "ユーザー1", user2: "ユーザー2"} puts hash.key?(:user1) puts hash.key?(:user3)
[実行結果]
true false
検索結果が真理値で返ってきたのがわかります。
ハッシュの値を検索する
今度はキーではなく値を検索してみます。値の検索は、value?とhas_value?の2つが存在しています。
考え方は、先ほどのキー検索とまったく同じです。
hash = {user1: "ユーザー1", user2: "ユーザー2"} puts hash.value?("ユーザー1") puts hash.value?("ユーザー3")
[実行結果]
true false
検索結果が真理値で返ってきたのがわかります。
まとめ
本記事では、ハッシュとシンボルについて解説しました。
ハッシュやシンボルは、Ruby on railsでも頻繁に使います。この記事を読んで完全に理解してくださいね!