迭代器中的Ruby赋值

时间:2010-10-19 05:24:00

标签: ruby

我想使用以下代码将名称“JOHN DOE-SMITH”转换为“John Doe-Smith”:

name = "JOHN DOE-SMITH"  
name_split = name.split(/\s/)  
name_split.each do |x|  
  if x =~ /-/  
    name1, name2 = x.split(/-/)  
    x = name1.capitalize + "-" + name2.capitalize  
  else  
    x.capitalize!  
  end  
end  
puts name_split.join(" ")  

结果是意外的“John DOE-SMITH” 为什么x.capitalize!有效,而x =“foo”没有?
有更好的方法吗?

3 个答案:

答案 0 :(得分:1)

x = "foo"只需指定变量x即可引用其他对象。由于该变量仅存在于块中,因此没有可观察到的影响。它根本不会改变字符串。另一方面,x.capitalize!capitalize!消息发送到字符串,这会导致更改大小写。

答案 1 :(得分:0)

因为x是一个使用相同数据指向字符串的局部变量。这就是为什么影响它的新值不会在字符串内部发生变化的原因。

你可能想在这里重新考虑一下你的策略;它取决于分裂字符串引用与原始字符串相同的内存区域这一事实,我不认为在所有情况下都是如此。
我建议改用.map:

name_split = name.split(/\s/).map do |x|
  if x =~ /-/
    name1, name2 = x.split(/-/)
    name1.capitalize + "-" + name2.capitalize
  else
    x.capitalize
  end
end  
puts name_split.join(" ")

或者如果您觉得这更具可读性:

name_split = name.split(/\s/).map do |x|
  x.split(/-/).map(&:capitalize).join('-')
end
puts name_split.join(" ")

答案 2 :(得分:0)

怎么样

cap_name = name.split.map{|w| w.split("-").map(&:capitalize).join("-") }.join(" ")