为什么Ruby中的嵌套.map方法对我的情况来说很奇怪?

时间:2015-12-03 20:48:53

标签: ruby dictionary methods nested

也许这样做并不常见,但无论如何。我很好奇为什么它不起作用。 我遇到了一个我不完全理解的奇怪行为。

string = "sdsdasda asdas asdas"
words = string.split

words.map! do |word|
    word.split(//).map! do |character|
        character.upcase #or any other operations that change character
    end.join
end

p words.join(" ")

如果我而不是奇怪的“end.join”构造这个

    end
    word.join
end

我收到错误,因为| word |尽管使用

,仍然保持不变(字符串而不是大写)
.map!
带有感叹号的

所以基本上我的问题是为什么地图!不会改变这个词。

2 个答案:

答案 0 :(得分:1)

正在.map!的结果上调用

.split(//)。它正在修改结果数组,而不是原始word

您可以考虑将.split(//)置于新变量中的结果:

characters = word.split(//)
characters.map! do |character|
  character.upcase
end

return characters.join
# `word` is not modified

答案 1 :(得分:0)

块中的最后一行代码确定返回上一循环的值。

通过向.join添加end,您实际上是想要将该代码块的结果返回到之前的map!调用。但是,当您之后添加其他行以明确执行word.join时,您表示要将word.join的结果返回到之前的map!调用。正如Leny Sirivong指出的那样,word仍然是小写的(您可以通过在那里打印word来确认。)

考虑这种替代语法,使其更清晰:

string = "sdsdasda asdas asdas"
words = string.split

words.map! do |word|
    result = word.split(//).map! {|character|character.upcase }.join
    p "word: " + word
    p "result: " + result
end

p words.join(" ")

你会在这里看到它确实有效,因为我将循环的结果分配给一个新的变量result。然后,result将传回原始map!来电而非word

"word: sdsdasda"
"result: SDSDASDA"
"word: asdas"
"result: ASDAS"
"word: asdas"
"result: ASDAS"

如果你运行这个,你会在这种情况下看到最终结果打印["result: SDSDASDA", "result: ASDAS", "result: ASDAS"]。那是因为我的循环的最后一行是p "result: " + result