Machida.rb #05に参加しました!
毎月第1金曜日に開催されているMachida.rbに、前回に引き続き2回目の参加をしました!
【目次】
今回はRubyで簡単な問題を解いてレビューし合う勉強会でした💪その中の問題を抜粋して書きます。
Rubyの問題を解いてみた
FizzBuzz
有名なFizzBuzz問題の省略版です。1~20の数字を出力するうち、3の倍数ではFizz・5の倍数ではBuzz・3と5の倍数ではFizzBuzzと出力させます。
最初のコードはこちら。
(1..20).each {|num| if num % 15 == 0 puts "fizzbuzz" elsif num % 3 == 0 puts "fizz" elsif num % 5 == 0 puts "buzz" else puts num end }
このコードで注目したのは「putsを毎回書いている」という点です。
これは以下のようにif文を()で括りそれに対してputsすることで、何度も書いていた部分が改善できるようになりました。
(1..20).each {|num| puts (if num % 15 == 0 "fizzbuzz" elsif num % 3 == 0 "fizz" elsif num % 5 == 0 "buzz" else num end) }
しかしさらに、「putsの位置」について改善できます。
上記ではループ処理の中にputsを置いているのですが、それより以下の書き方では「処理の結果(戻り値)を出力している」ことになるのでこちらの方がより良いとのことです。
puts (1..20).map {|num| if num % 15 == 0 "fizzbuzz" elsif num % 3 == 0 "fizz" elsif num % 5 == 0 "buzz" else num end }
パタトクカシーー
出題は言語処理100本ノックより「パタトクカシーー」問題です。
文字列の奇数番を取り出して「パトカー」と連結した文字列を取得します。
はじめに解いたコードはこちらなのですが、nilが出力されてしまってうまく出力ができませんでした😓
str = "パタトクカシーー" p str.chars.each_slice(2) {print _1[0]} # => パトカーnil
この原因はeach_slice(n) {|list| ... } -> nil
のように、each_sliceの戻り値がnilを返すためでした。※
文頭にp
を書いてしまっているため、この戻り値nilを拾って出力してしまっていました。
参考:リファレンスマニュアルEnumerable#each_slice
なので、こちらだったらいけますね。
putsは内部でto_sしてるいるのでnilは出力されません。
str = "パタトクカシーー" puts str.chars.each_slice(2) {print _1[0]} # => パトカー
しかしこれもまた、ブロック内部でprintをしてしまっているので、FizzBuzzの所に書いたように「戻り値を出力する」という方針でこちらの方が良いです↓
str = "パタトクカシーー" puts str.chars.each_slice(2).map { _1[0] }.join # => パトカー
※ちなみにeach_slice(n) -> Enumerator
のように、blockを持たなければeach_sliceの戻り値はEnumeratorになります。
感想
その場で解くにはちょうどいい問題の難易度で、人のコードと比較したり、すぐにレビューを受けられる&質問できるとても充実した勉強会でした! p・print・putsの挙動や適切な配置、Enumerator関連のメソッド(each_slice)がブロックを持つ時の戻り値がnilであることなど、学びもたくさんありました! また勉強会後の懇親会では、rubykaigiの直後だったこともありkaigi内の発表のことやruby3.0について技術的な話が聞けてとても楽しかったです!