ruby 将JSON转换为Struct?

eulz3vhy  于 12个月前  发布在  Ruby
关注(0)|答案(3)|浏览(77)

如何将JSON字符串转换为Struct而不是默认值(默认值是Hash,基本上可以使用attr_accessor s之类的方法访问哈希键)。
换句话说,我真的希望能够写obj.my_json_property来访问数据。

xytpbqjk

xytpbqjk1#

如果OpenStruct是可接受的(这仍然可以将结构体用作obj.my_json_property,即它满足原始要求),使用这种方法:

require 'json'
obj = JSON.parse(json_text, object_class: OpenStruct)
puts obj.my_json_property

我尝试使用object_class: Struct,但它给了我“TypeError:分配器未定义的结构”。然而,对于 * 大多数 *(但不是全部)实际用途,OpenStruct就很好。主要的缺点是,如果你拼错了一个属性名,你的代码运行得很好,值将只是nil/空字符串(取决于上下文)。这可能有点烦人和误导。
这有点像Hash#[]Hash#fetch(参考,请参阅:http://devblog.avdi.org/2009/03/16/go-fetch/)。

ljsrvy3e

ljsrvy3e2#

下面是一个将Hash转换为Struct的快速方法:

class Hash
    def to_struct
        s = Struct.new(*self.keys.map(&:to_sym))
        construct = map do |k,v|
            v.is_a?(Hash) ? v.to_struct : v.is_a?(Array) ? v.join(", ") : v
        end
        s.new(*construct)
    end
 end

然后你可以做这样的事情:

h = {hello: 'world',foo: {bar: 'baz'}}
m = h.to_struct
#=> #<struct hello="world", foo=#<struct bar="baz">>
m.hello
#=> "world"
m.foo
#=> #<struct bar="baz">
m.foo.bar
#=> "baz"

在你的例子中:

require 'json'
obj = JSON.parse(json_text).to_struct

可以很好地工作,它也可以处理嵌套对象(Array需要一些明显的处理 * 我只是没有打扰这部分,因为它不是问题的一部分)

v9tzhpje

v9tzhpje3#

使用Struct.new创建一个新类,并使用所需的访问器将其作为object_class传递给JSON.parse

> require 'json'
> MyStruct = Struct.new(:my_json_property)
> obj = JSON.parse('{"my_json_property": "foo"}', object_class: MyStruct)
=> #<struct  my_json_property="foo">
> obj.my_json_property
=> "foo"

相关问题