我们说我有以下代码块:
arr = ['a','b','c']
arr.map {|item| item <<'1'} #=> ['a1','b1','c1']
arr #=> ['a1','b1','c1']
为什么Array#map
会更改数组?它应该只创建一个新的。当我在块中使用+
而不是<<
时,它会按预期工作。 Array#each
是否会更改数组本身,还是仅对其进行迭代并自行返回?
答案 0 :(得分:4)
我的问题是:为什么
map
会更改数组?它应该只创建新的。
map
不会更改Array
。但<<
更改了String
中的Array
。
请参阅the documentation for String#<<
:
str << obj → str
追加 - 将给定对象连接到
str
。
虽然未明确提及,但代码示例清楚地表明<<
会改变其接收者:
a = "hello "
a << "world" #=> "hello world"
a.concat(33) #=> "hello world!"
这很奇怪,因为当我在
+
的块中使用<<
运算符时,它会按预期工作。
+
不会更改String
中的Array
。
请参阅the documentation for String#+
:
str + other_str → new_str
连接 - 返回一个新的
String
,其other_str
连接到str
。
请注意它是如何显示“new String
”的,并且返回值也是new_str
。
我的第二个问题:
Array#each
是否会更改数组本身,或者只是迭代数组并返回自身?
Array#each
不会更改Array
。但当然,传递给Array#each
的块可能会也可能不会更改Array
的元素:
arr = %w[a b c]
arr.map(&:object_id) #=> an array of three large numbers
arr.each {|item| item <<'1' } #=> ['a1', 'b1', 'c1']
arr.map(&:object_id) #=> an array of the same three large numbers
正如您所看到的,Array#each
并未更改Array
:它仍然是具有相同三个元素的Array
。
答案 1 :(得分:2)
使用map
或each
会对外部数组产生影响(map
将返回一个新数组,each
将返回原始数组),但它不会数组包含哪些字符串的差异;在任何一种情况下,数组中包含的字符串都将是修改后的原始字符串。