PerlerのRuby日記

Rubyとか

配列の要素が、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とか、桁数に限らずチェックはできそう。