在Ruby中递归展平数组

在Ruby中递归展平数组,ruby,recursion,Ruby,Recursion,我很难理解这段代码的工作原理: def flatten(array, result = []) array.each do |element| if element.is_a? Array flatten(element, result) else result << element end end result end flatte方法破坏性地修改第6行中的第二个参数result,并将修改后的数组作为参数传递给第4行中的

我很难理解这段代码的工作原理:

def flatten(array, result = [])
  array.each do |element|
    if element.is_a? Array
      flatten(element, result)
    else
      result << element
    end
  end
  result
end

flatte
方法破坏性地修改第6行中的第二个参数
result
,并将修改后的数组作为参数传递给第4行中的递归调用。无需从该方法返回任何内容,因为作为第二个元素传递的任何数组都将被破坏性修改,以附加平坦版本的输入数组:

my_array = [:foo]

flatten([1, [2, [3, [4]]]], my_array)

my_array
#=> [:foo, 1, 2, 3, 4]
通常认为,修改作为参数传递的对象或通过修改输入参数而不是仅仅返回值来返回值是不好的形式。看起来代码是由一个C程序员编写的,他想使用第二个参数作为输出缓冲区

更惯用的Ruby版本如下所示:

def flatten(array)
  array.each_with_object([]) do |element, result|
    if element.is_a?(Array)
      result.concat(flatten(element))
    else
      result << element
    end
  end
end
站点上可能还有更多,但简单的回答是,将
数组结果
传递给函数就是传递实际对象,而不是它的副本,并且对象由
结果修改
my_array = [:foo]

flatten([1, [2, [3, [4]]]], my_array)

my_array
#=> [:foo, 1, 2, 3, 4]
def flatten(array)
  array.each_with_object([]) do |element, result|
    if element.is_a?(Array)
      result.concat(flatten(element))
    else
      result << element
    end
  end
end
def flatten(array)
  array.inject([]) do |result, element|
    result + if element.is_a?(Array)
      flatten(element)
    else
      [element]
    end
  end
end