配列の要素が、1ずつ増加しているかどうかをチェックする
配列内の要素が1ずつ増えているかどうかをチェックしたかったメモ。
[1, 2, 3, 4] #=> OK [1, 2, 4] #=> NG [4, 5] #=> OK [6] #=> OK [7, 8, 0] #=> NG
今回自分が出くわした場面では、要素内の値が0〜9ということが確定していたので、こんな解決方法を思いついた。
ary = [1, 2, 3, 4] ok_str = (0..9).to_a.join #=> "0123456789" if ok_str.index(ary.join) puts "OK!" else puts "NG." end
あらかじめ0から9までの数字を連結させた文字列を用意して、String#indexでひっかけるやり方である。
まあでもかなり特殊な条件だし、ぱっと見て何をしているか親切ではないので、何かないですかね〜とチームメイトに相談したら、Array#each_consというのを教えてもらった。
ary = [1, 2, 3, 4] ary.each_cons(2) do |v1, v2| puts "v1: #{v1}, v2: #{v2}" end #=> v1: 1, v2: 2 #=> v1: 2, v2: 3 #=> v1: 3, v2: 4
https://ruby-doc.org/core-2.5.0/Enumerable.html#method-i-each_cons
順繰りにまとめたものをループしてくれる。すばらしい。
なので、0〜9とかに限らず、ちゃんと1ずつ増加しているかどうかを確認するやり方をeach_consを使ってみると、
ary = [1, 2, 3, 4] result = ary.each_cons(2) do |v1, v2| if (v1 + 1) != v2 break false end end if result.nil? puts "OK!" elsif result == false puts "NG." end
こんな感じかな。each_consは正常に回りきったらnilを返してくれるので、途中でだめだったときにそれ以外の値でbreakして切り分けるのがちょっとかっこ悪いけど、これなら0〜100とか300〜89654とか、桁数に限らずチェックはできそう。