map
如何将原始数组更改为不应该的位置?
arr = ['Foo','Bar','Tango']
arr.map do |name|
name[0] = 'A'
end
arr # => ["Aoo", "Aar", "Aango"]
为什么map!
中的同一块会产生完全不同的回报?
arr = ['Foo','Bar','Tango']
arr.map! do |name|
name[0] = 'A'
end
arr # => ["A", "A", "A"]
答案 0 :(得分:4)
在第一个示例中,map
生成一个新数组(由于未分配给var,因此会立即丢弃该数组),但该块包含修改包含的对象的副作用在数组中(即,没有触及数组本身,但没有什么能阻止你从数组中获取对象并更改它 - 如果它是可变的;而顺便说一句,字符串是可变的,事实上{{ 1}})。
在第二个示例中,s = "hi"; s[0]="x"; s # => "xi"
确实更改了原始数组,其中包含块的结果值,即每个元素的map!
(它是赋值表达式的结果,顺便提一下还会修改数组的原始元素 - 但是它们会被丢弃,因为它们会根据'A'
的语义进行替换。
来自ruby-doc:
map!
:为self的每个元素调用给定的块一次。创建一个新数组,其中包含块返回的值。map { |item| block } → new_ary
:为self的每个元素调用给定的块一次,用块返回的值替换元素。答案 1 :(得分:2)
map
如何将原始数组更改为不应该的位置?arr = ['Foo','Bar','Tango'] arr.map do |name| name[0] = 'A' end arr # => ["Aoo", "Aar", "Aango"]
没有。 map
不会更改数组,您的数据块会更改。实际上,要非常精确:块也不会更改数组,它会更改数组的每个元素。
为什么
map!
中的同一块会产生完全不同的回报?arr = ['Foo','Bar','Tango'] arr.map! do |name| name[0] = 'A' end arr # => ["A", "A", "A"]
没有。示例中map
和map!
的返回值相同。 (好吧,不是真的:map
返回一个 new 数组,map!
返回相同的数组,修改,但这两个返回数组的内容他是一样的。)但是你甚至从来没有看过返回值,你只是忽略它,那么你怎么能做出返回值不同的陈述呢?
map!
通过用块的值替换每个元素来改变数组。该块包含一个赋值表达式,赋值表达式计算到它们的左侧,ergo块返回每个元素的'A'
,这意味着每个元素都被'A'
替换。
请注意map
做同样的事情:
arr = %w[Foo Bar Tango]
new_arr = arr.map do |name| name[0] = 'A' end
arr #=> ["Aoo", "Aar", "Aango"]
new_arr #=> ["A", "A", "A"]