Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

【究極ガイド】Rubyのハッシュとは?定義・実例・主要メソッドを徹底解説

Rubyのハッシュとは?

ハッシュ(Hash)は、データを一意なキーと値のペアとして格納するためのデータ構造です。配列とは異なり数値のインデックスを持たず、値にはキーを使ってアクセスします。

具体的な活用例:

  • 国名とそれに対応する国コードの一覧(例:ES ⇾ スペイン)
  • 辞書:すべての単語に複数の定義が紐づいている
  • ドメイン名とIPアドレスの対応表

Rubyプログラムの中でハッシュを適切な場面で使えば、コードの処理速度を向上させることができます。

つまり、こういうことです:

データが辞書のような形式である(またはその形式に変換できる)場合、つまりキーとそれに紐づく値でデータをグループ化できるケースでは、ハッシュが最適な選択肢になります。

ハッシュの作り方

ハッシュの概要はわかりましたが、実際にはどうやって作るのでしょうか?

答えはシンプルです:

{}

これが空のハッシュです!

3つのキー/値ペアを持つハッシュは次のように書きます:

{ a: 1, b: 2, c: 3 }

ここで a がキー、1 がそのキーに対応する値です。キーと値のペアはカンマで区切ることに注意してください。

それでは:

よく使われるハッシュメソッドとともに、Rubyプロジェクトでハッシュをどのように活用できるのかを見ていきましょう。

Rubyハッシュへの値の保存

すでに見たように、初期値をセットした状態でハッシュを作成できます。

別の例を見てみましょう:

fruits = { coconut: 1, apple: 2, banana: 3 }

もうひとつの方法は、既存のハッシュに新しい値を追加することです。

このように書きます:

fruits[:orange] = 4

この例では :orange がハッシュのキー、4 がそれに対応する値になります。

なぜ値にアクセスするときはコロンの位置が :orange のように単語の前になり、ハッシュを作成するときは orange: のように後ろになるのか、不思議に思ったことはありませんか?これは「ハッシュロケット」(=>)記号を使わずにハッシュを作れる、より読みやすい構文です。ハッシュロケットも有効な書き方ですが、やや古いスタイルにあたります。

値には任意のRubyオブジェクトを指定できます。

たとえば:

  • 文字列
  • 整数・浮動小数点数
  • 配列

キーにも何でも使えますが、実務で最もよく見かけるのはシンボル(:banana など)と文字列です。

覚えておきましょう…

キーは一意です。:orange:apple というキーは、それぞれ1つしか存在できません。

同じキーを2回追加すると、値が上書きされます。

ハッシュから値を取り出す方法

ハッシュへのアクセスは、キーを通じて行います。

もし値へ直接アクセスする必要があるなら、そのデータにはハッシュが適していないかもしれません。

例:

fruits[:orange]
# 4

これこそがハッシュの本質です。キーを使って素早くアイテムを検索できます。

存在しないキーを指定すると、nil が返ります。

fruits[:peach]
# nil

代わりに fetch メソッドを使うと、デフォルト値を指定できます。

例:

fruits.fetch(:peach, 0)

fetch をデフォルト値(第2引数)なしで使うと、Rubyは KeyError 例外を発生させます。

これはとても便利です。どのキーが欠けているのかが明確になるからです。

2つのRubyハッシュをマージする方法

2つのハッシュを1つの新しいハッシュに統合することができます。

どんなメソッドを使うのでしょうか?

名前から推測できる通り、merge メソッドです。

使い方はこちら:

defaults    = { a: 1, b: 2, c: 3 }
preferences = { c: 4 }

defaults.merge!(preferences)
# {:a=>1, :b=>2, :c=>4}

キーは一意であるため、新しい値が古い値を上書きすることに注目してください。

この仕組みを利用すれば、「デフォルト設定」のハッシュを用意しておき、ユーザーが独自のハッシュを渡すことで上書きできる、といった応用的な実装も可能です。

キーのマージ方法をより細かく制御したい場合は、ブロックを渡します。

このように:

defaults.merge!(preferences) { |key, old, new| [old, new].max }

ここで olddefaults 側の値、newpreferences 側の値です。

1つのキーに複数の値を持たせる

辞書では…

単語は一意ですが、1つの単語に複数の値(定義)が紐づいています。

Rubyでも同じことができます!

例:

dictionary = {
  opportunity: [
    "a set of circumstances that makes it possible to do something",
    "a situation or condition favorable for attainment of a goal"
  ],
  creativity: [
    "the use of imagination or original ideas to create something new",
    "the ability to create",
    "the process where new ideas emerge from combining existing ideas in new ways"
  ]
}

dictionary[:creativity][1]

dictionary[:creativity] は配列を返し、続く [1] はその配列の2番目の要素を取り出します。

つまり:

キーはシンボル、値は配列という構造です。ハッシュにアクセスすると配列が返ってくるので、通常の配列とまったく同じように操作できます。

ハッシュをソートする方法

配列はソートできますが、ハッシュもソートできることをご存知でしたか?

ハッシュを sort すると、キー順に並べ替えられます。

例:

{ b: 1, a: 2 }.sort

# [[:a, 2], [:b, 1]]

値でソートすることもできます:

{ c: 3, b: 1, a: 2 }.sort_by(&:last)

ここでお気づきの方もいるでしょう。ハッシュをソートした結果は、別のハッシュではなく…

配列です!

ただし、to_h メソッドを使えば、この配列を再びハッシュに変換できます。

ハッシュのすべてのキーと値を取得する

ハッシュの全キーのリストが欲しいとき、朗報です。そのためのメソッドが用意されています!

こちらです:

{ apple: 1, banana: 2 }.keys

# [:apple, :banana]

値を含む配列を返すメソッドもあります:

{ apple: 1, banana: 2 }.values

# [1, 2]

配列として取得するのではなく、特定のキーがハッシュ内に存在するかどうかだけを確認したい場合は、key? メソッドを使います。

このメソッドは true または false を返します。

まとめ

この記事では、キーと値のペアで構成される便利なデータ構造「Rubyのハッシュ」について学びました。キーによるハッシュへのアクセス方法や、新しいデータの保存方法も理解できたはずです。

さっそくirb(またはpry)を開いて、ハッシュをいろいろと試してみましょう!

最後までお読みいただきありがとうございました🙂

  1. Ruby開発者のための時間計算量とBig O記法 徹底解説ガイド

    時間計算量は、コンピュータサイエンスの中でも最も興味深い概念のひとつです。しかも、特別な学位がなくても十分に理解できます。 この概念が面白いのは、あるアルゴリズムやプログラムがなぜ遅いのかを見抜き、どうすれば高速化できるのかを明確にしてくれる点にあります。 もちろん、自分が書いたコードにもすぐに応用できます。 さらに、教科書に載っているような高度なアルゴリズムだけではなく、日常的に書くコードにも役立つのがポイントです。本記事の後半で実際に確認していきます。 まずは、「遅い」と「速い」の定義から整理しましょう。 「遅い」と「速い」の定義 100万個の数字を150ミリ秒(ms)でソートするのは、果

  2. Rubyの配列(Array)クラスの使い方徹底解説!基本操作と便利なメソッド一覧

    配列(Array)とは? 配列はRubyに組み込まれたクラスで、0個以上の要素をリスト形式で保持することができます。さらに、要素の追加・アクセス・繰り返し処理を簡単に行えるメソッドも多数用意されています。 もし配列が存在しなければ、値ごとに個別の変数を用意しなければならず、管理が非常に大変になります。 例: a = 1 b = 2 c = 3 しかし、配列を使えば次のように書けます: numbers = [1, 2, 3] さらに嬉しいことに、配列の中には何でも入れられます! 例えば: 数値 文字列 さらに別の配列!(これは多次元配列になります) それでは、配列を最大限に活用できる