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

时间:2011-12-05 17:37:55

标签: 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 

其中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 

3 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:6)

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

这是否“不那么复杂”取决于观众。


减少重复和复杂性应该关注宏观行为,而不是微观重构短的,已经可读的方法。

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

增强应用,课程和方法文档会更好吗?这些文档应该在代码中还是在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

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

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

原始版本(最快):

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

答案 2 :(得分:4)

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

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

编辑:注册@tokland的评论。