Ruby连接字符串的最佳实践

3

我希望以聪明的方式解决Ruby中的一个简单问题。我有一个函数:

def fullname
  first + " " + mi + last
end

如果其中一个或多个变量为nil,那么这将导致崩溃,假设这里的变量是mi,因为它位于中心位置。

错误:

无法将nil转换为字符串

如果我将函数更改为:

def fullname
  first + " " + mi.to_s + last
end

或者

def fullname
  first + " " + (mi || "") + last
end

它会修复它。现在,如果中间名(middle initial)存在,我想在mi后面添加一个额外的空格,但由于某种愚蠢的原因,我被卡住了。最干净的方法是什么,因为我将不得不经常这样做,有时添加逗号等。

需要进行此操作的示例:

def fullname
  first + " " + (mi || "") + last + suffix 
  # want a ", " afer the last name if there is a suffix
end

1
你不应该依赖于全名具有定义的模式:http://www.w3.org/International/questions/qa-personal-names - Damien MATHIEU
2
@DamienMATHIEU:朋友,要一步一步来。这篇帖子的作者自称是新手,请不要让他感到过于压力。 ;) - Dan Tao
非常感谢,我完全明白这还没有国际化。在跨越那个桥之前,需要掌握一些基本技能。感谢您的文章,这是我需要阅读和理解的内容! - MechDog
3个回答

9

首先,我认为处理这个问题最符合“Ruby”的方式——避免nil问题的方法是使用字符串插值

"#{first} #{mi} #{last}"

如果上述任何变量为nil,那么这个方法就可以正常工作,因为它会在字符串中产生空格。

至于条件空格问题:有很多方法可以解决这个问题。我非常喜欢sawa的想法。这里有另一种方法,我看过类似的变体,尽管它不是特别高效(但九成的情况下这并不重要):

[first, mi, last].compact.join(" ")

最后:对于“加上逗号和后缀(如果有)”的要求,建议编写一个小方法来分离该逻辑,因为这部分比较复杂。

def suffix_if_necessary(name)
  suffix ? "#{name}, #{suffix}" : name
end

def fullname
  suffix_if_necessary([first, *mi, last].join(" "))
end

但是,这里有多种方法可以完成工作。无论哪种方式适合您。


那看起来肯定更干净。如果没有mi变量,我想的没错的话,名字的第一个和最后一个之间会有两个空格而不是一个? - MechDog
@MechDog:没错,你说得对。我刚刚更新了答案,以满足你对条件空格的要求。我承认,这并不是特别高效的方法;但由于这只是三个小字符串,性能和内存影响应该可以忽略不计。 - Dan Tao
谢谢你的帮助!这两个解决方案似乎都可以运行,我相信每个解决方案都有它的用武之地。感谢你们帮助我解决了困难!从你和@sawa那里学到了很多东西,非常感谢你们的时间和努力!!! - MechDog

7
def fullname
  [[first, *mi, last].join(" "), *suffix].join(", ")
end

非常感谢,对于空格这方面的处理很出色!有没有什么调整可以让它有时是一个空格,有时是一个逗号?我会更新我的问题以更好地反映这一点。 - MechDog
尽管它是这种情况的解决方案,但您真的不应该使用这种晦涩的代码。一眼看不出它生成了一个字符串,因此可能会让您之后阅读代码的人感到困惑。请考虑使用字符串插值代替。 - Shoe
@Jeffrey,你能否使用字符串插值法回答一下? - sawa
1
哈哈,我以为我可以接受超过一个。抱歉,我需要学习更多关于接口的知识。如果你不能展示愚蠢,那就没有意义了;-) - MechDog
@Jeffrey Dan Tao关于插值的回答存在一个问题:当mi不存在时,会插入一个额外的空格。 - sawa
显示剩余9条评论

1
我建议您使用字符串插值来清楚地表明从该方法返回的是一个字符串(并且还会忽略 nil 值):
def fullname
    s = "#{first} #{mi} #{last}".lstrip.rstrip.squeeze(' ')
    s += ", #{suffix}" if suffix
end

那如何处理可选的 suffix - sawa
你说这不是神秘的吗? - sawa
@sawa,最神秘的是String#+=方法。你猜猜看。此外,这并没有迭代任何数组(特别是多维数组),因此在理论上,与你的解决方案相比,复杂度较小。 - Shoe
我认为你发布这个是想展示你可以用插值得到一个不像我的那样“神秘”的答案。 - sawa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接