この記事はOkinawa.rb Advent Calendar 2018の18日目の記事です。
昨日は @hanachin_ さんのRuby 2.6のASCII以外の大文字で定義できる定数を試すでした。
明日は @hanachin_ さんの凸凹のRSpec平らに均すshared_contextがマジ便利です。
やってみた記事です
10分間隔で 10時〜23時代の配列をつくるが面白そうだったので書いてみました
文字列で10ずつ回して時刻っぽくない部分を弾く
("10:00".."23:50").step(10).select {|t| t.match?(/:[0-5]0/) }
数字で10ずつ回して時刻っぽくない部分を弾く
(1000..2350).step(10).select {|t| t % 100 < 60 }.map(&:to_s).each {|s| s[2,0] = ?: }
10から23と00から50を組み合わせ
("10".."23").to_a.product(("00".."50").step(10).to_a).map {|t| t.join(?:) }
("10".."23").flat_map {|h| ("00".."50").step(10).map {|m| "#{h}:#{m}" } }
時刻のことはTimeにおまかせ
Time.new(0, 1, 1, 10, 0).then {|t| loop.lazy.map { t.tap { t += 10 * 60 } }.take_while {|t| t <= Time.new(0, 1, 1, 23,
50) }.map {|t| t.strftime("%H:%M") }.to_a }
Enumerator.new {|y| t = Time.new(0, 1, 1, 10, 0); while t <= Time.new(0, 1, 1, 23, 50); y << t.strftime("%H:%M"); t +=10 * 60; end }.to_a
まとめ
- 10進数の繰り返しは
step
がべんり - 数字も文字列も
step
できる -
Array#product
は2つの配列を組み合わせることができてべんり - 24進数と60進数など進数が違うものをネストしてループしてまとめるときは外側で
flat_map
するとべんり - 時刻を一定間隔で繰り返しするときなど何かしら普段繰り返さないものを繰り返したいときは
Enumerator
やloop.lazy.map
とtake_while
の組み合わせを使うとべんり