如何用数组编组哈希?

我该怎么做来编组数组的哈希? 以下代码仅打印{}

 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次(这可能是转储中显示的内容),但它不会在哈希中存储任何内容。 尝试“put s [8]”,它会返回[[“Tigger”],[“Ruth”],[“Puuh”]]。

Hash.default_proc会做你想要的

 s = Hash.new{|hash,key| hash[key]=[] } 

但你无法组织一个过程。 这将有效:

 s = Hash.new s.default = Array.new s[0] += ["Tigger"] s[7] += ["Ruth"] s[7] += ["Puuh"] 

这是有效的,因为[] + = [“Tigger”]创建一个数组。 另一种方法是创建更少的数组:

 s = Hash.new (s[0] ||= []) << "Tigger" (s[7] ||= []) << "Ruth" (s[7] ||= []) << "Puuh" 

仅在密钥不存在时才创建新数组(nil)。

您可以在初始化Hash.new时创建哈希结构以避免此类问题

 h = Hash.new{ |a,b| a[b] = [] } h[:my_key] << "my value" 

您可能会被误导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" ps 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 ps data = Marshal.dump(s) ls = Marshal.restore( data ) p ls 

由于你不能在带有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