Ruby:在Ruby中优雅的数组初始化和返回

ste*_*her 6 ruby functional-programming initialization

我有一个方法:

def deltas_to_board_locations(deltas, x, y)
    board_coords = []
    deltas.each_slice(2) do |slice|
      board_coords << x + slice[0] 
      board_coords << y + slice[1]
    end
    board_coords
  end 
Run Code Online (Sandbox Code Playgroud)

其中deltas是一个数组,x,y是fixnums.

有没有办法消除第一行和最后一行,使方法更优雅?

喜欢:

def deltas_to_board_locations(deltas, x, y)
    deltas.each_slice(2) do |slice|
      board_coords << x + slice[0] 
      board_coords << y + slice[1]
    end
  end 
Run Code Online (Sandbox Code Playgroud)

tok*_*and 7

deltas.each_slice(2).flat_map do |dx, dy|
  [x + dx, y + dy]
end
Run Code Online (Sandbox Code Playgroud)


Dav*_*ton 6

deltas.each_with_index.map { |val, idx| val + (idx % 2 == 0 ? x : y )}
Run Code Online (Sandbox Code Playgroud)

这是否"不那么复杂"取决于观众.


减少重复和复杂性应该集中在宏观行为而不是微重构短的,已经可读的方法.

这种重写是否会导致量化的易于理解的系统?还是有更重要,更高层次的问题?

增强应用程序,类和方法文档会更好吗?这些文档应该在代码中还是在wiki中?一张图片值得一千行吗?


与@ tokland相比的表现比较(他的胜利数量很大).假设deltas是一个百万元素阵列1-1m.MRI,Ubuntu,老pokey机器.

我的版本

deltas.each_with_index.map { |val, idx| val + (idx % 2 == 0 ? x : y )}

Total: 1.764807

 %self     total     self     wait    child    calls  name
100.00      1.76     1.76     0.00     0.00        1  Array#each
  0.00      1.76     0.00     0.00     1.76        1  Global#[No method]
  0.00      1.76     0.00     0.00     1.76        2  Enumerable#each_with_index
  0.00      1.76     0.00     0.00     1.76        1  Enumerable#map
  0.00      1.76     0.00     0.00     1.76        1  Enumerator#each
Run Code Online (Sandbox Code Playgroud)

更好,更短,更具沟通性的版本

deltas.each_slice(2).flat_map { |dx, dy| [x + dx, y + dy] }

Total: 1.236144

 %self     total     self     wait    child    calls  name
100.00      1.24     1.24     0.00     0.00        1  Array#each
  0.00      1.24     0.00     0.00     1.24        1  Global#[No method]
  0.00      1.24     0.00     0.00     1.24        2  Enumerable#each_slice
  0.00      1.24     0.00     0.00     1.24        1  Enumerable#flat_map
  0.00      1.24     0.00     0.00     1.24        1  Enumerator#each
Run Code Online (Sandbox Code Playgroud)

原始版本(最快):

Total: 0.899122

 %self     total     self     wait    child    calls  name
100.00      0.90     0.90     0.00     0.00        1  Array#each
  0.00      0.90     0.00     0.00     0.90        1  Global#[No method]
  0.00      0.90     0.00     0.00     0.90        1  Enumerable#each_slice
Run Code Online (Sandbox Code Playgroud)


Dom*_*nef 4

deltas.each_slice(2).flat_map { |dx, dy|
  [x + dx, y + dy]
}
Run Code Online (Sandbox Code Playgroud)

以上适用于 Ruby 1.9 ,但我同意 Renaud 的观点。显而易见的解决方案是首选,在这种情况下也比我的更快。

编辑:合并@tokland的评论。