プログラミング漫遊記

思ったことや、勉強したことをつらつらと。

【Ruby】ハッシュを使って条件分岐を減らそう!

こんにちは「はるぐち」です。フィヨルドブートキャンプで学習しています。 今回はある値によってたくさんの条件分岐をしたいとき、ハッシュを使うとシンプルになることを学んだので忘備録として記述しておきたいと思います。

想定

果物がたくさん入った配列があります(たくさんとは)。この中からランダムに1つ取り出したとき、値段が返ってくるブログラムを考えます。

仮にpriceメソッドとでも名付けましょう。 以下のような出力を期待します。(果物の値段は勘で決めました)

fruits = ['apple', 'banana', 'melon', 'pineapple']

price(fruits.sample) # ランダムに1つ選ぶ
#=> apple: 120円
#=>とか
#=> banana: 60円
#=>とか
#=> melon: 3000円
#=>とか
#=> pineapple: 800円
#=> となる

if文を使う場合

まずはif文*1で書いていきます。 elsifでの条件分岐が多いので読みにくい感じがします。

fruits = ['apple', 'banana', 'melon', 'pineapple']

def price(fruit)
  price = 
    if fruit == 'apple'
      120
    elsif fruit == 'banana'
      60
    elsif fruit == 'melon'
      3000
    elsif fruit == 'pineapple'
      800
    end
  puts "#{fruit}: #{price}"
end

price(fruit.sample)

果物が増えたとき、elsif fruit == 果物 値段と記述しないといけないためかなり面倒です。 そして何回も書くfruit ==が結構しんどい。あーなくしたいなぁ〜。

case文を使う場合

特定の値による条件分岐が多い場合はcase文*2を使うことも多いと思います。

fruits = ['apple', 'banana', 'melon', 'pineapple']

def price(fruit)
  price =
    case fruit
    when 'apple'
      120
    when 'banana'
      60
    when 'melon'
      3000
    when 'pineapple'
      800
    end
  puts "#{fruit}: #{price}"
end

price(fruits.sample)

if文のときと比べると、fruit ==の部分がないので少しだけ、本当に少しだけスッキリはしました。 また、値段を戻り値とするだけの処理なのでthenを使って1行で記述してもいいような気がします。

fruits = ['apple', 'banana', 'melon', 'pineapple']

def price(fruit)
  price =
    case fruit # thenを使って1行で記述
    when 'apple' then 120
    when 'banana' then 60
    when 'melon' then 3000
    when 'pineapple' then 800
    end
  puts "#{fruit}: #{price}"
end

price(fruits.sample)

ただ、この場合も果物が増えるごとにwhen 果物 then 値段という文を増やさないといけません。

そこで、ハッシュを使ってみます。

ハッシュを使う場合

ハッシュを使うと条件分岐が消え、果物を追加するときも楽に追加することができます。 つまり、管理も簡単ということです。

fruits = ['apple', 'banana', 'melon', 'pineapple']

def price(fruit)
  price = 
  {
    'apple' => 120,
    'banana' => 60,
    'melon' => 3000,
    'pineapple' => 800
  }[fruit]
  puts "#{fruit}: #{price}"
end

price(fruits.sample)

引数として受け取った果物がハッシュのキーとなって値段を返しています。 条件分岐が消えてシンプルで見やすくなりましたし、果物を追加するのも簡単です。

また果物と値段のhashを使い回すときは定数として定義しておくのもいいかも知れません。

fruits = ['apple', 'banana', 'melon', 'pineapple']

FRUITS_TABLE = {
  'apple' => 120,
  'banana' => 60,
  'melon' => 3000,
  'pineapple' => 800
}

def price(fruit)
  price = FRUITS_TABLE[fruit]
  puts "#{fruit}: #{price}"
end

price(fruits.sample)

まとめ

  • ハッシュを使ったら条件分岐をなくすことができる。
  • 条件の変更や条件そのものを増やしたり減らしたりすることも簡単!

つまり、ハッシュすごい!

もっといい方法があればぜひ教えてください。

*1:正確にはif式ですがここではif文で統一しています。そのほかも同じ扱いです。

*2:*1に同じく