2

我正在尝试反转字符串变量数组中的单词,但 split 似乎不起作用。

在 IRB 中测试我得到“NoMethodError: private method `split' called for Array”,我假设这与我的程序悄悄地什么都不做有关。

例如,我有:

nameList = ["Joe Blow", "Mary Sue", "Alice Mallory"].

我希望返回:

["Blow Joe", "Sue Mary", "Mallory Alice"].

所以我遍历数组,拆分,反转和加入。这是没有任何反应的地方:

nameList.each { |x| 
  x.to_s.split(' ').reverse!.join(' ')
  puts x   #testing here
}

这输出:

Joe Blow
Mary Sue
Alice Mallory

我一定错过了一些非常简单的东西,因为这不会太难。

4

3 回答 3

7

您正在拆分、反转和丢弃结果。看一下这个。

nameList = ["Joe Blow", "Mary Sue", "Alice Mallory"]

nameList.each { |x| 
  puts x.to_s.split(' ').reverse.join(' ')
  puts x
  puts '' # for easier reading   
}
# >> Blow Joe
# >> Joe Blow
# >> 
# >> Sue Mary
# >> Mary Sue
# >> 
# >> Mallory Alice
# >> Alice Mallory
# >> 

如果您想对数组的每个元素进行一些转换,获取新值并构造这些值的新数组,使用Array#map函数是惯用的。

nameList = ["Joe Blow", "Mary Sue", "Alice Mallory"]

newList = nameList.map { |x| 
  x.to_s.split(' ').reverse.join(' ')
}

另外,在这里你不应该使用 bang 版本的 reverse ( reverse!)。它具有破坏性语义。reverse创建一个新的反向数组,同时reverse!更新源数组。在这种情况下,源数组是一个临时变量,因此在结果方面没有区别。但我认为它令人困惑和分散注意力。

于 2012-05-28T18:36:17.507 回答
2

精简版:

nameList.map!{ |x| x.split.reverse.join(' ') }
#=> ["Blow Joe", "Sue Mary", "Mallory Alice"]
于 2012-05-28T20:09:17.183 回答
0

问题

Ruby 中的一切都有一个返回值。在这种情况下,您没有使用方法链的返回值;您只是在打印原始值。

nameList.each { |x| 
  # Returns a result, but you aren't doing anything with it.
  x.to_s.split(' ').reverse!.join(' ')

  # Here you print your original value.
  puts x   #testing here
}

解决方案

执行此操作的简单方法是使用#collect,它返回一个数组。

p nameList.collect { |name| name.split.reverse.join(' ') }
["Blow Joe", "Sue Mary", "Mallory Alice"]
=> ["Blow Joe", "Sue Mary", "Mallory Alice"]

这将打印一个修改后的数组,并返回一个数组作为进一步处理的结果。或者,如果你真的想改变你的数组,你可以像这样分配结果:

nameList = nameList.collect { |name| name.split.reverse.join(' ') }
 => ["Blow Joe", "Sue Mary", "Mallory Alice"] 
nameList
 => ["Blow Joe", "Sue Mary", "Mallory Alice"]

当然还有其他方法可以做到这一点,但保持可读性很重要。在这种情况下,保持将数组分配给变量的语义是有意义的,这样意图就很清楚了。

于 2012-05-28T20:17:49.423 回答