做一些測試後,我發現,如果你曾經有一個更深層次的架構,你最終運行到與這些算法的問題,因爲分裂的關鍵只在密鑰中佔一個點('。')。如果你有更多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