我尝试了:
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]
#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
或者 splice:
a1[a1.length, 0] = a2
a1[a1.length..0] = a2
a1.insert(a1.length, *a2)
或者追加和展平:
(a1 << a2).flatten! # a call to #flatten instead would return a new array
Array#concat
进行数组连接操作时不会创建新的数组,而使用Array#+
进行连接操作则会创建一个新的数组。 - cbliard+
操作符!irb(main):001:0> a = [1,2]
=> [1, 2]
irb(main):002:0> b = [3,4]
=> [3, 4]
irb(main):003:0> a + b
=> [1, 2, 3, 4]
您可以在这里阅读有关数组类的所有信息: http://ruby-doc.org/core/classes/Array.html
a+= b
将创建一个新数组:c = a = [1,2] ; b = [3,4] ; a += b ; puts c #=> [1,2]
- kbrockpush
方法。 - Joshua Pinter+=
会创建一个新的对象。在这个例子中 [1, 2].each_with_object([]) { |number, object| object+=number }
,将返回空数组 []
。 - Filip Bartuzi最干净的方法是使用Array#concat方法;它不会创建一个新的数组(与Array#+不同,后者会做同样的事情但会创建一个新的数组)。
来自文档的原话(http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-concat):
concat(other_ary)
将other_ary的元素附加到self上。
因此:
[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方法,它会在执行连接之前自动展平多维数组。a = ["some", "thing"]
b = ["another", "thing"]
a
和b
相加并将结果存储在a
中:a.push(*b)
或者
a += b
a
都会变成:["some", "thing", "another", "thing"]
但在前一种情况下,b
的元素会被追加到现有的 a
数组中,在后一种情况下,这两个数组会被连接在一起,并将结果存储在 a
中。
a.push(*b)
与a += b
并不完全相同。前者将新元素添加到现有数组中,后者创建一个包含所有元素的新数组,并将其分配给a
。如果您在任一附加方法之前执行aa = a
以保存对a
的引用,然后检查aa
,您可以看到差异。在前一种情况下,它随着a
的新值而更改,而在后一种情况下,它保持不变。 - Dave Hartnolleach_with_object
使用等非常重要。使用each_with_object([]) { |thing, result| result += [thing] }
是行不通的,而使用push
方法则可行。 - ragurney这是一种简单的方法,适用于Ruby版本>= 2.0,但不适用于旧版本:
irb(main):001:0> a=[1,2]
=> [1, 2]
irb(main):003:0> b=[3,4]
=> [3, 4]
irb(main):002:0> c=[5,6]
=> [5, 6]
irb(main):004:0> [*a,*b,*c]
=> [1, 2, 3, 4, 5, 6]
*
是什么意思? 这里的 *
是一个指针符号,用于解引用指针。它可以访问指针所指向的值。 - Abhinay[*a, *b]
在旧版本的 Ruby(即 1.8.7)中会失败。尽管 Ruby 想告诉你它已经过时了,但 RHEL6 仍在维护中,使得 Ruby 1.8 仍然是一个重要的目标版本。 - Otheus[...array1, ...array2]
的方式,只需记住在Ruby中的splat
运算符是*
而不是...
。这样更容易记住。 - sandre89这里有两种方式,注意在这种情况下第一种方式会分配一个新数组(翻译为 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"]
试一下这个方法,它可以将你的数组合并并去除重复项。
array1 = ["foo", "bar"]
array2 = ["foo1", "bar1"]
array3 = array1|array2
http://www.ruby-doc.org/core/classes/Array.html
查看更多“Set Union”文档。
array1 |= [ "foo1", "bar1" ] #=> [ "foo", "bar", "foo1", "bar1" ]
- Joshua Pinter(array1 + array2).uniq
这样,您将首先获取array1的元素。您将不会获得任何重复项。
在 @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
操作在数组足够大时会引发一个错误:stack level too deep (SystemStackError)
。
["some", "thing"] + ["another", "thing"]
[*a] + [*b]
是可行的。 - Otheus"another" + "thing"
相加不会按预期工作。 - Alexis Wilke
Array#flatten!
是“原地”将数组压平。如果没有进行修改(即数组不包含子数组),则返回nil。 - yeyoflatten!
的工作方式不同,所以没有得到。最后,这个问题反映了一个逻辑问题而不是一个优化问题。请参见下面pilcrow的答案获取更多信息。 - yeyo