LoginSignup
13
4

More than 1 year has passed since last update.

【Ruby】ネストしたHashをselectメソッドを使って検索する方法

Last updated at Posted at 2022-10-13

今回行いたいこと

@drinks{:cola=>{:price=>120, :stock=>5},:redbull=>{:price=>200, :stock=>5},:water=>{:price=>100, :stock=>5}}
@slot_money = gets.to_i
  • 上記のHashの:priceの値と@slot_moneyを比較し、購入可能なドリンクのみを入れたリストを作りたい。また、在庫がある商品のみをリストに表示する。

実装条件をもとに考えたこと

  • リストを作りたいので、リストを返すメソッドを使用する。
  • 比較しなければいけないので、Hashの中身を検索できるメソッドを使用する必要がありそう。
    =>find, find_all, selectなど…?

とりあえず、selectが条件に合いそうなので実験してみる。

selectメソッドについて

select -> Enumerator[permalink][rdoc][edit]
select {|key, value| ... } -> Hash
filter -> Enumerator
filter {|key, value| ... } -> Hash
key, value のペアについてブロックを評価し,真となるペアだけを含むハッシュを生成して返します。
ブロックが与えられなかった場合は、自身と select から生成した Enumerator オブジェクトを返します。
[使用例]
h = { "a" => 100, "b" => 200, "c" => 300 }
h.select {|k,v| k > "a"} #=> {"b" => 200, "c" => 300}
h.select {|k,v| v < 200} #=> {"a" => 100}
引用:https://docs.ruby-lang.org/ja/latest/method/Hash/i/filter.html

  • 公式リファレンスでは、上記のように記載があるためとりあえず{}内にkeyとvalueを記載する必要がありそう。
@drinks.select{|drink, content| ...}

ここでつまづきました...
|drink, content|以降の条件を書く部分になんて書いたらええんや...

しかし、ここで天啓が降りてきました。

 「pメソッド使って中身覗いたろ」と。

  • その結果できたコードと結果がこちらです。
irb:> @drinks.select{|drink, content| p drink}
:cola
irb> @drinks.select{|drink, content| p content}
{:price=>120, :stock=>5}
注:ここではHashの中身が増えるとわかりつらいため、ひとつだけ入れております。
  • 結果を見て分かる通り、drinkを指定した際はcolaが、contentを指定した際は、{:price=>120, :stock=>5}が取得できています。

ここで、更なる閃きが起きました。

「contentの中身がHashならcontent[:price]とかにしたらpriceの値が取得できるんじゃないか?」

ならば、やってみましょう。

irb> @drinks.select{|drink, content| p content[:price]}
120

取れちゃいましたね~

  • ここまで分かれば、あとは簡単です。selectメソッドの条件部分に検索する条件を記載しましょう。

検索条件は「Hashの:priceの値と@slot_moneyを比較し、購入可能なドリンクのみを入れたリストを作りたい。また、在庫がある商品のみをリストに表示する。」です。

irb> @slot_money = 120 #120円お金を持っています。

irb> @drinks #@drinksにコーラとレッドブルと水を入れています。
=> 
{:cola=>{:price=>120, :stock=>5},
 :redbull=>{:price=>200, :stock=>5},
 :water=>{:price=>100, :stock=>5}}

irb> @drinks.select{|drink, content| content[:price] <= @slot_money 
&& content[:stock] > 0 }
=> {:cola=>{:price=>120, :stock=>5}, :water=>{:price=>100, :stock=>5}} #120円で買える商品のリストを取得できました。

無事にリストを取得できました!!

  • リストをよく見ると120円で買える商品のみのリストを取得できています。
    レッドブルは200円で120円では購入できないため、リストに入っていません。

まとめ

  • 今回のケースでは、鍵となるのが、ネストしたHashのkeyとvalueに何が代入されるかという部分でした。
    実際に、keyとvalueを確認しながら検証を行うことで値の取り出し方についてHashの基本となる方法のみで取り出すことができました。

今後もこまめに変数の中身を確認しながら作業していきたいと思います。

13
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
4