我不知道这是否真的是好的ruby代码,但我想要做的是将一个String分成两个独立的部分,并将两个值作为两个特定键的值。例如:
name_a = "Henry Fillenger".split(/\s+/,2)
name = {:first_name => name_a[0], :last_name => name_a[1]}
我想知道这是否可以通过一些红宝石魔法在一行中完成。
答案 0 :(得分:18)
您可以使用Hash[]
和zip
执行此操作:
name = Hash[ [:first_name, :last_name].zip("Henry Fillenger".split(/\s+/,2)) ]
但是我会说你的版本更具可读性。并非一切都必须在一条线上。
答案 1 :(得分:7)
还有两行,但在我看来,可读性略高,
first_name, last_name = "Henry Fillenger".split(/\s+/,2)
name = {:first_name => first_name, :last_name => last_name}
答案 2 :(得分:2)
只是为了好玩,一个非拆分变体(也是两行):
m = "Henry Fillenger".match(/(?<first_name>\S+)\s+(?<last_name>\S+)/)
name = m.names.each_with_object({ }) { |name, h| h[name.to_sym] = m[name] }
有趣的部分是正则表达式中的命名捕获组((?<first_name>...)
)和使用each_with_object
的一般哈希化技术。命名的捕获组需要1.9。
如果一个人大胆,可以将each_with_object
位修正为MatchData
,例如to_hash
:
class MatchData
def to_hash
names.each_with_object({ }) { |name, h| h[name.to_sym] = self[name] }
end
end
然后你可以拥有你的单行:
name = "Henry Fillenger".match(/(?<first_name>\S+)\s+(?<last_name>\S+)/).to_hash
我不是真的推荐这个,我只是把它作为一个兴趣点。我对MatchData
已经没有to_h
或to_hash
方法感到有点失望,它会对其to_a
方法做出明智的补充。