如何重构此代码以删除输出变量?

时间:2013-10-06 19:11:34

标签: ruby refactoring

def peel array
  output = []

  while ! array.empty? do
    output << array.shift
    mutate! array
  end

  output.flatten
end

我没有包含变异!方法,因为我只对删除输出变量感兴趣。变异!调用很重要,因为我们无法使用每个数组迭代数组,因为数组正在发生变化。

编辑:我得到一个数组作为输出,这是我想要的。该方法正常工作,但我认为有一种方法可以在不使用临时变量的情况下收集array.shift值。

编辑#2:好的,这是变异!方法和测试用例:

def mutate! array
  array.reverse!
end

a = (1..5).to_a
peel( a ).should == [ 1, 5, 2, 4, 3 ]

peel修改数组无关紧要。我想它应该被称为peel!。是的,必须在删除每个元素后调用mutate!

3 个答案:

答案 0 :(得分:1)

所有这些逆转让我头晕目眩。

def peel(array)
  indices = array.size.times.map do |i|
    i = -i if i.odd?
    i = i/2
  end 
  array.values_at(*indices) # indices will be [0, -1, 1, -2, 2] in the example
end

a = (1..5).to_a
p peel(a) #=>[1, 5, 2, 4, 3]

答案 1 :(得分:1)

另一种方法:

def peel(array)
  mid = array.size/2
  array[0..mid]
    .zip(array[mid..-1].reverse)
    .flatten(1)
    .take(array.size)
end

用法:

peel [1,2,3,4,5,6]
#=> [1, 6, 2, 5, 3, 4]

peel [1,2,3,4,5]
#=> [1, 5, 2, 4, 3]

答案 2 :(得分:0)

以下是使用并行分配的方法:

def peel array
  n = array.size
  n.times {|i| (n-2-2*i).times {|j| array[n-1-j], array[n-2-j] = array[n-2-j], array[n-1-j]}}
  array      
end

peel [1,2,3,4,5] # => [1,5,2,4,3]
peel [1,2,3,4,5,6] # => [1,6,2,5,3,4]

我在这里做的是一系列成对交换。举例来说,对于[1,2,3,4,5,6],前6-2 = 4步(6是数组的大小)改变数组如下:

[1,2,3,4,6,5]
[1,2,3,6,4,5]
[1,2,6,3,4,5]
[1,6,2,3,4,5]

1,6和2现在处于正确的位置。我们重复这些步骤,但这次只有6-4 = 2次,将5和3移动到正确的位置:

[1,6,2,3,5,4]
[1,6,2,5,3,4]

4被推到最后,这是正确的位置,所以我们完成了。