我试着:
somearray = ["some", "thing"]
anotherarray = ["another", "thing"]
somearray.push(anotherarray.flatten!)
我预期的
["some", "thing", "another", "thing"]
但有
["some", "thing", nil]
我试着:
somearray = ["some", "thing"]
anotherarray = ["another", "thing"]
somearray.push(anotherarray.flatten!)
我预期的
["some", "thing", "another", "thing"]
但有
["some", "thing", nil]
当前回答
详细阐述@Pilcrow的答案,对于大型数组唯一合适的答案是concat(+),因为它速度快,并且在循环中操作时不会分配一个新对象来进行垃圾回收。
下面是基准:
require 'benchmark'
huge_ary_1 = Array.new(1_000_000) { rand(5_000_000..30_000_00) }
huge_ary_2 = Array.new(1_000_000) { rand(35_000_000..55_000_00) }
Benchmark.bm do |bm|
p '-------------------CONCAT ----------------'
bm.report { huge_ary_1.concat(huge_ary_2) }
p '------------------- PUSH ----------------'
bm.report { huge_ary_1.push(*huge_ary_2) }
end
结果:
user system total real
"-------------------CONCAT ----------------"
0.000000 0.000000 0.000000 ( 0.009388)
"------------------- PUSH ----------------"
example/array_concat_vs_push.rb:13:in `block (2 levels) in <main>': stack level too deep (SystemStackError)
正如你所看到的,当数组足够大时,使用push会抛出ERROR:堆栈级别太深(SystemStackError)。
其他回答
["some", "thing"] + ["another", "thing"]
这里有两种方法,注意在这个例子中,第一种方法分配一个新数组(转换为somearray = somearray + anotherarray)
somearray = ["some", "thing"]
anotherarray = ["another", "thing"]
somearray += anotherarray # => ["some", "thing", "another", "thing"]
somearray = ["some", "thing"]
somearray.concat anotherarray # => ["some", "thing", "another", "thing"]
a = ["some", "thing"]
b = ["another", "thing"]
将b追加到a并将结果存储在a中:
a.push(*b)
or
a += b
在这两种情况下,a都变成:
["some", "thing", "another", "thing"]
但在前一种情况下,b的元素被追加到现有的a数组中,在后一种情况下,两个数组连接在一起,结果存储在a中。
最简洁的方法是使用array# concat方法;它不会创建一个新数组(不像array# +会做同样的事情,但创建一个新数组)。
直接从文档(http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-concat):
concat (other_ary) 将other_ary的元素追加到self。
So
[1,2].concat([3,4]) #=> [1,2,3,4]
如果作为参数传入多维数组,array# concat将不会平展多维数组。你需要单独处理:
arr= [3,[4,5]]
arr= arr.flatten #=> [3,4,5]
[1,2].concat(arr) #=> [1,2,3,4,5]
最后,您可以使用我们的corelib gem (https://github.com/corlewsolutions/corelib),它为Ruby核心类添加了有用的帮助程序。特别地,我们有一个array# add_all方法,它将在执行concat之前自动将多维数组平展。
你有一个可行的想法,但#flatten!在错误的地方——它会使接收器变平,所以你可以用它把[1,2,['foo', 'bar']]变成[1,2,'foo','bar']。
毫无疑问,我忘记了一些方法,但你可以串联起来:
a1.concat a2
a1 + a2 # creates a new array, as does a1 += a2
或预先考虑/追加:
a1.push(*a2) # note the asterisk
a2.unshift(*a1) # note the asterisk, and that a2 is the receiver
或接头:
a1[a1.length, 0] = a2
a1[a1.length..0] = a2
a1.insert(a1.length, *a2)
或append和flatten:
(a1 << a2).flatten! # a call to #flatten instead would return a new array