我正在尝试有条件地映射我拥有的数组:
看起来像[“a”,“b”,“c”]
的数组我想将其内联映射(使用map!)来更改匹配/ b /的任何内容并将其更改为“bb”。这似乎不起作用,它似乎没有改变数组。
我希望它看起来像这样[“a”,“bb”,“c”]
定义数组:
irb(main):001:0> a = [ "a", "b", "c" ]
=> ["a", "b", "c"]
尝试使用链接到地图的选择!,它显示一个元素的更改值,并且它不会更改原始数组。
irb(main):002:0> a.select { |e| e =~ /b/ }.map! { |e| e = "bb" }
=> ["bb"]
irb(main):003:0> p a.inspect
"[\"a\", \"b\", \"c\"]"
所以我尝试做同样的事情,但是将它分配给一个新的数组,这只会创建一个包含任何已更改元素的数组 - 而不是我想要的
irb(main):004:0> cc = a.select { |e| e =~ /b/ }.map! { |e| e = "bb" }
=> ["bb"]
irb(main):005:0> p cc.inspect
"[\"bb\"]"
=> nil
我在这里缺少什么?我想在这里缺少一些Ruby基础知识。
答案 0 :(得分:4)
您在select
上致电a
,该Array
会返回map!
的新实例,您将在下一步调用a.map! { |e| e =~ /b/ ? 'bb' : e }
,修改此新实例(不是原始实例)一)。要实现您的目标,您可以:
{{1}}
答案 1 :(得分:3)
正确的逻辑如下:
results = a.map { |e| if e =~ /b/ then "bb" else e end }
使用三元运算符的相同逻辑:
results = a.map { |e| e =~ /b/ ? "bb" : e }
如果您确实需要就地替换,请使用!
,如下所示:
a.map! { |e| e =~ /b/ ? "bb" : e }
这就是为什么你的帖子中的代码没有按照你期望的方式工作的原因:
您的select
正在返回一个新数组,然后map!
正在修改新数组。这是一个问题。
更重要的是,select
方法并不像您使用它一样有效。 select
方法仅返回 匹配的项目。
一般情况下,不要使用!
作为地图,除非你有充分的理由,而且你对它的了解更好,因为修改对象的Ruby !
方法往往是更难以调试和可靠地测试。