使用Array#map方法有些误解

时间:2014-04-06 11:57:16

标签: ruby

我们说我有以下代码块:

arr = ['a','b','c']
arr.map {|item| item <<'1'} #=> ['a1','b1','c1']
arr #=> ['a1','b1','c1']

为什么Array#map会更改数组?它应该只创建一个新的。当我在块中使用+而不是<<时,它会按预期工作。 Array#each是否会更改数组本身,还是仅对其进行迭代并自行返回?

2 个答案:

答案 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)

使用mapeach会对外部数组产生影响(map将返回一个新数组,each将返回原始数组),但它不会数组包含哪些字符串的差异;在任何一种情况下,数组中包含的字符串都将是修改后的原始字符串。