我有一个OpenStruct,它与许多其他OpenStructs嵌套在一起。将它们全部转换为JSON的最佳方法是什么?
理想情况是:
x = OpenStruct.new
x.y = OpenStruct.new
x.y.z = OpenStruct.new
z = 'hello'
x.to_json
// {y: z: 'hello'}现实
{ <OpenStruct= ....> }发布于 2015-10-13 00:19:33
没有默认的方法来完成这样的任务,因为内置#to_hash返回哈希表示,但它不会深入转换值。
如果一个值是一个OpenStruct,它就会以这样的方式返回,并且它不会被转换为Hash。
然而,这并不是很复杂的解决办法。您可以创建一个方法,该方法遍历OpenStruct实例中的每个键/值(例如使用each_pair),如果该值是OpenStruct,则递归下降到嵌套的OpenStruct中,并返回一个只有Ruby类型的Hash。
这样的Hash就可以很容易地使用.to_json或JSON.dump(hash)序列化。
这是一个非常快速的示例,通过@Yuval对OpenStructs数组的更新:
def openstruct_to_hash(object, hash = {})
case object
when OpenStruct then
object.each_pair do |key, value|
hash[key] = openstruct_to_hash(value)
end
hash
when Array then
object.map { |v| openstruct_to_hash(v) }
else object
end
end
openstruct_to_hash(OpenStruct.new(foo: 1, bar: OpenStruct.new(baz: 2)))
# => {:foo=>1, :bar=>{:baz=>2}}发布于 2017-08-17 18:25:44
修正上述解决方案以处理数组
def open_struct_to_hash(object, hash = {})
object.each_pair do |key, value|
hash[key] = case value
when OpenStruct then open_struct_to_hash(value)
when Array then value.map { |v| open_struct_to_hash(v) }
else value
end
end
hash
end发布于 2020-04-29 01:32:47
这里还有另一种方法,它是从lancegatlin的答案修改而来的。还将方法添加到OpenStruct类本身。
class OpenStruct
def deep_to_h
each_pair.map do |key, value|
[
key,
case value
when OpenStruct then value.deep_to_h
when Array then value.map {|el| el === OpenStruct ? el.deep_to_h : el}
else value
end
]
end.to_h
endhttps://stackoverflow.com/questions/33092107
复制相似问题