Ruby Array・Hash の練習問題(後半)

Ruby Array・Hash の練習問題(前半) - No Solution for Life の続き。後半の5問目〜8問目。

attracie.hatenablog.com

Q5

[:a, :b, :c]
# を
[ { a: 1 }, { b: 2 }, { c: 3 } ]
# に変換する

自分の解答

p [:a, :b, :c].map.with_index(1) { |s, i| { s => i } }

Q6

{ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }
# を
[ :b, :d, :f ]
# に変換する(valueが偶数のkeyだけ返す)

自分の解答

hash = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }
#=> [ :b, :d, :f ]
ans = []
hash.each do |k, v|
  ans << k if hash[k].even?
end
p ans

select を使った模範解答

p({ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }.select { |_, v| v % 2 == 0 }.keys)

_ の意味を初めて知った。

ブロックローカル変数を渡す時、ブロックの中で使用しないものは_にしておくのがちょっとした慣例です。

それから、前回のブログで pを使うとエラーになった件、コメントをいただいて無事解決した!ありがたや〜

今回も同じで、pの後に( )を書かずに以下のようにするとエラーになる。

# q6.rb  # エラーになる
p { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 }.select { |_, v| v % 2 == 0 }.keys

実行結果

$ ruby q6.rb 
q6.rb:9: syntax error, unexpected ':', expecting '}'
p { a: 1, b: 2, c: 3, d: 4, e: 5, f...

いつもデバッグなんかでpばっかり使っているが、これは知らなかった!ハマりポイントっぽいので覚えたい。

Q7

[1,2,3,4,5]
# を
120
# に変換(すべてかけ合わせる)

自分の解答

p [1, 2, 3, 4, 5].inject(:*)

Enumerable#inject (Ruby 2.7.0 リファレンスマニュアル)

injectも使い慣れていないが、この問題はinjectを使いたいと思ってリファレンスを見たら例があったのでパクっただけ。使えたのでうれしい。

Q8

{ taro: { result: true, score: 50 }, jiro: { result: false, score: 30 }, saburo: { result: true, score: 10 }, shiro: { result: false, score: 100 } }
# を
60
# に変換する(resultがtrueの人物のscoreを合計する)

自分の解答

hash = {
  taro: { result: true, score: 50 },
  jiro: { result: false, score: 30 },
  saburo: { result: true, score: 10 },
  shiro: { result: false, score: 100 }
}

ans = 0
hash.each do |k, v|
  ans += hash[k][:score] if hash[k][:result]
end
p ans

模範解答を見て気づいたが、hash[k]vと書くべきだった。

どうもハッシュはまだ手になじんでいない気がしているので、こういう問題ももっとやっていきたい。