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

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

例如:

FindSequence([9,8,7,5,4]) = [9,8,7] FindSequence([4,2,0]) = nil 

假设它是预先排序的,你可以很容易地测试直线:

 array.each_cons(2).all? { |x,y| y == x - 1 } 

为了安全起见,您可能需要添加排序:

 array.sort.each_cons(2).all? { |x,y| y == x + 1 } 

但是如果你真的需要提取最大的序列,那将需要另一个解决方案。

在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]] 

您可以获得所需的语义

 def find_longest_sequence(a) s = find_sequences_desc(a).max s unless s.size <= 1 end 

更新

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]] 

如果你说你已经排序和删除重复项,那么如果数组的第一个和最后一个元素之间的差异等于它们的索引的差异,则数组是顺序的。 (我在这里很模糊,因为我相信我的答案可以概括。)