如何用数组编组哈希?

时间:2010-03-31 11:15:52

标签: ruby serialization

我应该怎样做才能编组数组的哈希值? 以下代码仅打印{}

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

如果哈希不包含数组,则可以正确恢复。

4 个答案:

答案 0 :(得分:7)

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”]会创建一个 new 数组。 另一种方法是创建更少的数组:

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

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

您可能会误导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

答案 3 :(得分:0)

由于你不能在带有proc的默认元素的Hash上使用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