`each_with_object` 块内的 `+=` 和 `<<` 之间的区别
Difference between `+=` and `<<` inside a block for `each_with_object`
我不得不更新一个数组,我在传递给 Array#each_with_object
:
的块内的不同代码运行中使用了 +=
和 <<
代码 1
(1..5).each_with_object([]) do |i, a|
puts a.inspect
a += [i]
end
输出:
[]
[]
[]
[]
[]
代码 2
(1..5).each_with_object([]) do |i, a|
puts a.inspect
a << [i]
end
输出:
[]
[1]
[1,2]
[1,2,3]
[1,2,3,4]
+=
运算符不会更新原始数组。为什么?我在这里错过了什么?
在each_with_object
中,所谓的备忘录对象在迭代中很常见。您需要修改该对象才能做一些有意义的事情。 +=
运算符是 +
和赋值的语法糖,它不会修改接收者,因此迭代没有效果。如果你使用像<<
或push
这样的方法,那么它就会生效。
另一方面,在inject
中,所谓的memo对象就是block的return值,不需要修改对象,但是需要return 下一次迭代所需的值。
It is clear to me that += operator is not updating the original array. Why?
因为 the documentation 这么说(强调我的):
ary + other_ary
→ new_ary
Concatenation — Returns a new array built by concatenating the two arrays together to produce a third array.
[ 1, 2, 3 ] + [ 4, 5 ] #=> [ 1, 2, 3, 4, 5 ]
a = [ "a", "b", "c" ]
c = a + [ "d", "e", "f" ]
c #=> [ "a", "b", "c", "d", "e", "f" ]
a #=> [ "a", "b", "c" ]
Note that
x += y
is the same as
x = x + y
This means that it produces a new array. As a consequence, repeated use of +=
on arrays can be quite inefficient.
See also #concat
.
比较 <<
ary << obj
→ ary
Append—Pushes the given object on to the end of this array. This expression returns the array itself, so several appends may be chained together.
[ 1, 2 ] << "c" << "d" << [ 3, 4 ]
#=> [ 1, 2, "c", "d", [ 3, 4 ] ]
Array#+
的文档明确说返回了一个new数组(实际上不少于四次)。这与 Ruby 中 +
方法的其他用法一致,例如Bignum#+
, Fixnum#+
, Complex#+
, Rational#+
, Float#+
, Time#+
, String#+
, BigDecimal#+
, Date#+
, Matrix#+
, Vector#+
, Pathname#+
, Set#+
, and URI::Generic#+
.
我不得不更新一个数组,我在传递给 Array#each_with_object
:
+=
和 <<
代码 1
(1..5).each_with_object([]) do |i, a|
puts a.inspect
a += [i]
end
输出:
[]
[]
[]
[]
[]
代码 2
(1..5).each_with_object([]) do |i, a|
puts a.inspect
a << [i]
end
输出:
[]
[1]
[1,2]
[1,2,3]
[1,2,3,4]
+=
运算符不会更新原始数组。为什么?我在这里错过了什么?
在each_with_object
中,所谓的备忘录对象在迭代中很常见。您需要修改该对象才能做一些有意义的事情。 +=
运算符是 +
和赋值的语法糖,它不会修改接收者,因此迭代没有效果。如果你使用像<<
或push
这样的方法,那么它就会生效。
另一方面,在inject
中,所谓的memo对象就是block的return值,不需要修改对象,但是需要return 下一次迭代所需的值。
It is clear to me that += operator is not updating the original array. Why?
因为 the documentation 这么说(强调我的):
ary + other_ary
→new_ary
Concatenation — Returns a new array built by concatenating the two arrays together to produce a third array.
[ 1, 2, 3 ] + [ 4, 5 ] #=> [ 1, 2, 3, 4, 5 ] a = [ "a", "b", "c" ] c = a + [ "d", "e", "f" ] c #=> [ "a", "b", "c", "d", "e", "f" ] a #=> [ "a", "b", "c" ]
Note that
x += y
is the same as
x = x + y
This means that it produces a new array. As a consequence, repeated use of
+=
on arrays can be quite inefficient.See also
#concat
.
比较 <<
ary << obj
→ary
Append—Pushes the given object on to the end of this array. This expression returns the array itself, so several appends may be chained together.
[ 1, 2 ] << "c" << "d" << [ 3, 4 ] #=> [ 1, 2, "c", "d", [ 3, 4 ] ]
Array#+
的文档明确说返回了一个new数组(实际上不少于四次)。这与 Ruby 中 +
方法的其他用法一致,例如Bignum#+
, Fixnum#+
, Complex#+
, Rational#+
, Float#+
, Time#+
, String#+
, BigDecimal#+
, Date#+
, Matrix#+
, Vector#+
, Pathname#+
, Set#+
, and URI::Generic#+
.