如何返回阵列中可能存在的一组序列号?

Jer*_*ith 2 ruby ruby-on-rails

如果我有一个排序数组,我如何找到序列号?顺便说一句,这是用于确定扑克牌是否是直线牌.数组中的重复项已被删除.我可以做到这一点,但这将是一个多行方法,我认为可能有一个使用Enumerable方法的快速单行.

例如:

FindSequence([9,8,7,5,4]) = [9,8,7]
FindSequence([4,2,0]) = nil
Run Code Online (Sandbox Code Playgroud)

J-_*_*_-L 8

在1.9.2中,一个神秘的slice_before方法被添加到Enumerable中.你可以利用它:

def find_sequences_desc(a)
  prev = a[0]
  a.slice_before { |cur|
    prev, prev2 = cur, prev  # one step further
    prev2 - 1 != prev        # two ago != one ago ? --> new slice
  }.to_a
end
# find_sequences_desc [9,8,7,4,4] #=> [[9, 8, 7], [4], [4]]
# find_sequences_desc [9,8,7,5,4] #=> [[9, 8, 7], [5, 4]]

def find_sequences_asc(a)
  prev = a[0]
  a.slice_before { |cur|
    prev, prev2 = cur, prev  # one step further
    prev2 + 1 != prev        # two ago != one ago ? --> new slice
  }.to_a
end
# find_sequences_asc [1,2,4,5,7] #=> [[1, 2], [4,5], [7]]
# find_sequences_asc [1,2,3,5,6] #=> [[1, 2, 3], [5, 6]]
Run Code Online (Sandbox Code Playgroud)

您可以获得所需的语义

def find_longest_sequence(a)
  s = find_sequences_desc(a).max
  s unless s.size <= 1
end
Run Code Online (Sandbox Code Playgroud)

更新

Ruby 2.2添加了slice_when方法,它简化了代码:

def find_sequences_desc(a)
  a.slice_when { |prev, cur|
    cur != prev - 1
  }.to_a
end
# find_sequences_desc [9,8,7,4,4] #=> [[9, 8, 7], [4], [4]]
# find_sequences_desc [9,8,7,5,4] #=> [[9, 8, 7], [5, 4]]
Run Code Online (Sandbox Code Playgroud)