Ruby:检测Array中转折点的最优雅方法

Eug*_*Zol 0 ruby arrays

我们来看以下数组:

[1, 4, 5, 3, 1, 4, 6, 5, 4]
Run Code Online (Sandbox Code Playgroud)

它具有以下转折点(当上升变化为下降时,反之亦然):

  • 5(索引2)
  • 1(索引4)
  • 6(索引6)

使任务更通用:

  • 有一个数组 a = [a1, a2, ...]
  • 有功能p(x,y) -> z,这里zComparable
  • 如何获得的所有元素 ∈一个(0 <I <则为a.length-1)其中p(一个I-1 ,一个)!= P(A ,一个I + 1)

我想写一些类似的东西:

a.detect_edges{|prev, n| prev >= n} # => [[5,2], [1, 4], [6,6]]
Run Code Online (Sandbox Code Playgroud)

用各自的指数获得转折点的最优雅方法是什么?这是我的代码,从美学的角度来看,我不满意:

class Array
  def detect_edges(&blk)
    return nil if self.length < 2
    prev = blk.call(self[0], self[1])
    result = []
    self[0..-2].each_with_index do |elem, i|
      current = blk.call(elem, self[i+1])
      if current != prev
        result.push [elem, i]
      end
      prev = current
    end
    result
  end
end
Run Code Online (Sandbox Code Playgroud)

saw*_*awa 5

[1, 4, 5, 3, 1, 4, 6, 5, 4]
.each_cons(3).with_index(1)
.reject{|(e1, e2, e3), i| (e1 <=> e2) == (e2 <=> e3)}
.map{|(e1, e2, e3), i| [e2, i]}
# => [[5, 2], [1, 4], [6, 6]]
Run Code Online (Sandbox Code Playgroud)

  • 这应该是一个月左右的答案. (2认同)