地图和地图的意外效果!在Ruby中

时间:2017-06-29 22:36:26

标签: arrays ruby

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"]

2 个答案:

答案 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"]

没有。示例中mapmap!的返回值相同。 (好吧,不是真的: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"]