做一些测试后,我发现,如果你曾经有一个更深层次的架构,你最终运行到与这些算法的问题,因为分裂的关键只在密钥中占一个点('。')。如果你有更多a.b.c
,算法会失败。
例如,给定:
{
'a' => 'a',
'b.a' => 'b.a',
'b.b' => 'b.b',
'c.a.b.c.d' => 'c.a.b.c.d',
'c.a.b.c.e' => 'c.a.b.c.e'
}
你所期望的:
{
'a' => 'a',
'b' => {'a' =>'b.a', 'b' => 'b.b'},
'c' => {
'a' => {
'b' => {
'c' => {
'd' => 'c.a.b.c.d',
'e' => 'c.a.b.c.e'
}
}
}
}
}
也有问题,如果数据试图覆盖的哈希值与标量或反之亦然:
{
'a3.b.c.d' => 'a3.b.c.d',
'a3.b' => 'a3.b'
}
或
{
'a4.b' => 'a4.b',
'a4.b.c.d' => 'a4.b.c.d'
}
这是最终版本。如果发生了其中一种不良情况,则这将引发参数错误。显然你可以捕捉到不好的数据版本,只需回显原始哈希值就行了。
def convert_from_dotted_keys(hash)
new_hash = {}
hash.each do |key, value|
h = new_hash
parts = key.to_s.split('.')
while parts.length > 0
new_key = parts[0]
rest = parts[1..-1]
if not h.instance_of? Hash
raise ArgumentError, "Trying to set key #{new_key} to value #{value} on a non hash #{h}\n"
end
if rest.length == 0
if h[new_key].instance_of? Hash
raise ArgumentError, "Replacing a hash with a scalar. key #{new_key}, value #{value}, current value #{h[new_key]}\n"
end
h.store(new_key, value)
break
end
if h[new_key].nil?
h[new_key] = {}
end
h = h[new_key]
parts = rest
end
end
new_hash
end
如果你想掌握红宝石,我要说的集中在红宝石的对象模型。 “红宝石之道”的书很好而且彻底。恐怕较短的书籍不会给你对Ruby的深刻见解。就代码而言,这基本上是迭代通过散列中的每个键 - 值对,将键以2(以点(。)为键)分开,并将分离的字符串分别构建为键和子键。其实很简单,如果你知道[Ruby Hash] [http://ruby-doc.org/core/classes/Hash.html] – Chirantan 2010-12-06 10:07:43