Ruby:如何将数组的数组连接成一个


72

我在Ruby on Rails(3.1)中有一个数组数组,其中所有内部数组的大小都不同。有没有一种方法可以轻松地将所有内部数组连接起来,以使所有项目都成为一个大的一维数组?

我知道您可以使用Array :: concat函数来连接两个数组,并且我可以做一个循环来依次连接它们,如下所示:

concatenated = Array.new
array_of_arrays.each do |array|
    concatenated.concat(array)
end

但是我想知道是否有像Ruby一样的衬纸可以更清洁地完成它。

谢谢你的帮助。


1
如所建议的,这flatten(1)是您想要的,但是我想指出的是,您可以将上面的内容写为array_of_arrays.reduce(:concat)
卡里·斯沃夫兰

Answers:


165

您正在寻找#flatten

concatenated = array_of_arrays.flatten

默认情况下,这将递归地平铺列表。#flatten接受一个可选参数来限制递归深度–文档列出了一些示例来说明差异。


24
更好flatten(1)。数组中的元素可以是数组本身,并且可以递归地展平。
tokland 2011年

可选参数需要Ruby 1.8.7或更高版本
user102008 2013年

也作为一般建议;建议使用它,flatten!(n)因为这会修改对象到位,而不是对其进行复制。通过减少需要完成的GC量,使用更改对象的方法可以提高性能。
ARu​​n32 '19

1
1.这是非常有效的巫术:d 2.我不会让一个一般的建议,尤其是现在,函数式编程是一个米姆。但即使不考虑这一点,我也认为一般来说,破坏输入是不好的,引用透明性是好的,并且应该使用bang方法作为优化,其中可观察的结果与使用副本相同,除非您有基于程序逻辑的理由想要暴露原位突变。
millimoose19年

28

或更笼统地说:

array_of_arrays.reduce(:concat)

这不会破坏3、4或5+维数组,而不会变平;)使用#flatten,您需要非常了解数组中包含的内容,因为这是一种递归方法,可能不希望这样做。
d11wtq 2011年

喔好吧。当我将其用于诸如此类的事情时,我会牢记这一点。在这种情况下,它不是很重要,因为它们是简单的数组,并且递归可以正常工作。
Pedro Cori

@ d11wtq:是的,这就是Ruby 1.9的原因flatten(n)
tokland 2011年

2
请注意,array_of_arrays如果您仍然打算在其他地方使用原始数组,则此代码将更改原始数组,这可能会导致问题。
mkataja '16

为避免更改原稿,可以执行array_of_arrays.reduce :+。但请注意,这两个回报的nil,如果array_of_arrays是空的,而flatten回报[]
蒂姆·史密斯

6

您可以使用拼合!方法。例如。 a = [ 1, 2, [3, [4, 5] ] ] a.flatten! #=> [1, 2, 3, 4, 5]


通过使用,a.flatten!您还可以防止复制数组,节省内存和垃圾回收。
ARu​​n32 '19
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.