連続数字をハイフンでつなぐ(Ruby)
既に更新はされていませんが、僕はブログ「hp12c」をよく読んでいます。Ruby 好きには楽しいですね。
そこで、「Rubyで連続数字をハイフンでつなぐよ」というエントリがありました。元ネタはここということです。やることは要するに、「スペース区切りの数字列を、数字が連続する場合にその箇所をハイフンにする」ということです。
"1 2 3" => "1-3." "1 2 3 5 7 8" => "1-3, 5, 7-8." "1 3 4 5 7" => "1, 3-5, 7."
こんな感じ。で、元ネタのも含めていろいろ Ruby の便利メソッドを使った華麗な回答がいくつもあるのですが、ふつうにというか、あんまり便利メソッドを使わない素直な回答を考えてみました。
こんな感じになりました。
def hyphenize(st) ar = st.split.map(&:to_i) compress = ->{ result = ar.first.to_s i = 0 i += 1 while ar[i].succ == ar[i + 1] result += "-" + ar[i].to_s if i.nonzero? ar = ar.drop(i + 1) result } str = "" str += compress.() + ", " until ar.empty? str[0..-3] + "." end
ちょっと長いし華麗でも何でもないですけれど、まあ素直だと思います。是非リンク先の凝った回答たちも見てみて下さい。
追記: クロージャの機能を使って書き換えてみました。変数ar
がクロージャcompress.()
に保持されています。
リンク先の回答例の中では、smileruby さんのこれが特に凝っていると思います。ただし、掲載されたコードは Ruby 2.5.1 では動かないので、多少変更しました。
def hyphenize(str) nums = str.scan(/\d+/).map(&:to_i).sort prev = nums.first nums.slice_before do |e| prev, prevprev = e, prev prevprev.succ != prev end.map {|e| e.minmax.uniq.join('-')}.join(', ') + '.' end
slice_before
とか minmax.uniq.join('-')
とか、凝っていますねえ。僕は思わずリファレンス・マニュアルを調べましたよ。