我應該怎麼做marshal散列數組? 以下代碼僅打印{}
。如何編組散列數據?
s = Hash.new
s.default = Array.new
s[0] << "Tigger"
s[7] << "Ruth"
s[7] << "Puuh"
data = Marshal.dump(s)
ls = Marshal.restore(data)
p ls
如果散列不包含數組,它將被正確恢復。
我應該怎麼做marshal散列數組? 以下代碼僅打印{}
。如何編組散列數據?
s = Hash.new
s.default = Array.new
s[0] << "Tigger"
s[7] << "Ruth"
s[7] << "Puuh"
data = Marshal.dump(s)
ls = Marshal.restore(data)
p ls
如果散列不包含數組,它將被正確恢復。
s = Hash.new
s.default = Array.new
s[0] << "Tigger"
s[7] << "Ruth"
s[7] << "Puuh"
此代碼更改默認的3次(這可能是轉儲中顯示的內容),但它不會在散列中存儲任何內容。嘗試「puts s [8]」,它會返回[[「Tigger」],[「Ruth」],[「Puuh」]]。
一個Hash.default_proc會做你想要
s = Hash.new{|hash,key| hash[key]=[] }
什麼,但你不能馬歇爾PROC。這將工作:
s = Hash.new
s.default = Array.new
s[0] += ["Tigger"]
s[7] += ["Ruth"]
s[7] += ["Puuh"]
這工作,因爲[] + = 「跳跳虎」]創建一個新陣列。 一種替代,產生更少的陣列:
s = Hash.new
(s[0] ||= []) << "Tigger"
(s[7] ||= []) << "Ruth"
(s[7] ||= []) << "Puuh"
只有創建新的數組當鍵不存在(無)。
您可能會誤解Hash.default
的工作原理。
之前你Marshal.dump
,打印數據結構。這是{}
。這是因爲您將每個字符串連接到nil,而不是一個空數組。下面的代碼說明並解決了您的問題。
s = Hash.new
s.default = Array.new
s[0] = []
s[0] << "Tigger"
s[7] = []
s[7] << "Ruth"
s[7] << "Puuh"
p s
data = Marshal.dump(s)
ls = Marshal.restore(data)
p ls
返回:
{0=>["Tigger"], 7=>["Ruth", "Puuh"]}
{0=>["Tigger"], 7=>["Ruth", "Puuh"]}
編輯:
我插入了大量的數據到哈希
因此,也許一些輔助代碼將使插入流程更流暢:
def append_to_hash(hash, position, obj)
hash[position] = [] unless hash[position]
hash[position] << obj
end
s = Hash.new
append_to_hash(s, 0, "Tigger")
append_to_hash(s, 7, "Ruth")
append_to_hash(s, 7, "Puuh")
s.default = Array.new // this is only for reading
p s
data = Marshal.dump(s)
ls = Marshal.restore(data)
p ls
你可以只創建哈希結構,同時草簽Hash.new避免這樣的麻煩
h = Hash.new{ |a,b| a[b] = [] }
h[:my_key] << "my value"
很好的答案,這比我的'append_to_hash'好得多。 – 2010-03-31 12:08:58
不幸的是,它給了我一個「無法轉儲散列與默認過程」編組錯誤。我想這是因爲[]的重新定義。 – Pascal 2010-03-31 12:21:47
你需要's.default = Array.new'或者你會得到那個錯誤。 – 2010-03-31 12:35:52
正如你不能用PROC一個散列使用Marshall.dump
默認元素,你可以使用添加到每個陣列,而不是<<
的稍微迂迴的方式:
s = Hash.new
s.default = []
s[0] += [ "Tigger" ]
s[7] += [ "Ruth" ]
s[7] += [ "Pooh" ]
data = Marshal.dump(s)
ls = Marshal.restore(data)
p ls
適合我:-)。比Julians append_to_hash更優雅,所以這是我的答案。 – Pascal 2010-03-31 13:02:29
重置默認也將工作:http://stackoverflow.com/questions/3818623/marshal-ruby-hash-with-default-proc-remove-the-default-proc – Ashitaka 2014-03-22 17:18:06