如何在数组中找到前两个连续元素?

时间:2017-06-27 18:17:29

标签: arrays ruby

使用Ruby 2.4,我有一组唯一的有序数字,例如

[1, 7, 8, 12, 14, 15]

如何找到差异为1的前两个元素?例如,上面的数组答案就是“7”和“8”。

5 个答案:

答案 0 :(得分:9)

您可以使用each_consfind从第二个元素减去第一个元素的第一个元素中获取第一个元素:

p [1, 7, 8, 12, 14, 15].each_cons(2).find { |a, b| b - a == 1 }
# => [7, 8]

答案 1 :(得分:4)

以下是另外三种方式。

<强>#1

def first_adjacent_pair(arr)
  (arr.size-2).times { |i| return arr[i, 2] if arr[i+1] == arr[i].next }
  nil
end

first_adjacent_pair [1, 7, 8, 12, 14, 15] #=> [7,8]
first_adjacent_pair [1, 7, 5, 12, 14, 16] #=> nil

<强>#2

def first_adjacent_pair(arr)
  enum = arr.to_enum # or arr.each
  loop do
    curr = enum.next
    nxt = enum.peek
    return [curr, nxt] if nxt == curr.next
  end
  nil
end
当枚举器enum.peek使用前面的StopIteration生成了最后一个元素时,

enum会引发enum.next异常。该异常由Kernel#loop通过断开循环来处理,之后返回nil。另请参阅Object#to_enumEnumerator#nextEnumerator#peek

<强>#3

def first_adjacent_pair(arr)
  a = [nil, arr.first] 
  arr.each do |n|
    a.rotate!
    a[1] = n
    return a if a[1] == a[0] + 1
  end
  nil
end

请参阅Array#rotate!

答案 2 :(得分:1)

简单示例

   X = [1, 7, 8, 12, 14, 15]

   X.each_with_index do |item, index|
    if index < X.count - 1
     if (X[index+1]-X[index] == 1) 
      puts item
     end
   end
  end

答案 3 :(得分:1)

这是为教育目的而提供的替代方法:

arr = [1, 7, 8, 12, 14, 15]

arr.each_cons(2).map {|v|v.reduce(:-)}.index(-1)

答案 4 :(得分:0)

一种方法:

a.each_with_index { |e, i| break [ e, a[i.next] ] if a[i.next] == e.next } 
#=> [7, 8]

chunkeach_cons不同,这不会创建数组数组。一旦找到它,它也会中断。

基准

require 'fruity'

arr = ((1...1000)).to_a.reverse + [1,2]

def first_adjacent_pair(arr)
  idx = arr.each_index.drop(1).find { |i| (arr[i-1]-arr[i]).abs == 1 }
  idx ? arr[idx-1, 2] : nil
end

def first_adjacent_pair2(arr)
  enum = arr.to_enum
  loop do
    curr = enum.next
    nxt = enum.peek
    return [curr, nxt] if (curr-nxt).abs == 1
  end
  nil
end

compare do
  iceツ  { ar = arr.dup; ar.each_with_index { |e, i| break [ e, ar[i.next] ] if ar[i.next] == e.next }  }
  cary   { ar = arr.dup; first_adjacent_pair(ar) }
  cary2  { ar = arr.dup; first_adjacent_pair2(ar) }  
  seb    { ar = arr.dup; ar.each_cons(2).find{|a,b| b-a == 1} }
end

#Running each test 64 times. Test will take about 1 second.
#cary2 is faster than cary by 3x ± 0.1
#cary is faster than iceツ by 3x ± 0.1 (results differ: [999, 998] vs [1, 2])
#iceツ is faster than seb by 30.000000000000004% ± 10.0%