Ruby:对于bang方法,#map通常没有意义吗?

时间:2017-01-25 15:08:25

标签: ruby

这个问题的灵感来自于这个问题: Ruby: Why does this way of using map throw an error?

有人指出以下内容:

使用时地图没有多大意义!方法。

你应该:

  • 使用地图与gsub
  • 或与gsub一起使用!

有人可以解释为什么会这样吗?

2 个答案:

答案 0 :(得分:2)

基础对象

这是一个以字符串作为元素的数组:

words = ['hello', 'world']

新数组

如果您想要一个包含已修改字符串的新数组,可以将mapgsub一起使用:

new_words = words.map{|word| word.gsub('o','#') }

p new_words
#=> ["hell#", "w#rld"]
p words
#=> ["hello", "world"]
p new_words == words
#=> false

原始字符串和原始数组未被修改。

在适当位置修改的字符串

如果要修改字符串,可以使用:

words.each{|word| word.gsub!('o','#') }
p words
#=> ["hell#", "w#rld"]

map和gsub!

new_words = words.map{|word| word.gsub!('o','#') }
p words
#=> ["hell#", "w#rld"]
p new_words
#=> ["hell#", "w#rld"]
p words == new_words
#=> true
p new_words.object_id
#=> 12704900
p words.object_id
#=> 12704920

这里创建了一个新数组,但元素完全相同!

它不会带来比前面的例子更多的东西。它无需创建新的数组。它也可能通过发送相反的信号来混淆阅读代码的人:

  • gsub!表示您要修改现有对象
  • map表示您不想修改现有对象。

答案 1 :(得分:1)

Map用于构建新数组而不会改变原始数组。每个都用于对数组的每个元素执行某些操作。一下子做两件事都很令人惊讶。

>> arr = ["foo bar", "baz", "quux"]
=> ["foo bar", "baz", "quux"]
>> arr.map{|x| x.gsub!(' ', '-')}
=> ["foo-bar", nil, nil]
>> arr
=> ["foo-bar", "baz", "quux"]

由于!-methods通常有副作用(并且偶然可能会返回一个值),因此在调用!-method时,each应优先于map

当您有要执行的操作列表时,可能会出现异常。执行操作的方法可能明智地以!命名,但您希望收集结果以报告哪些成功或失败。