如何将JSON字符串转换为Struct而不是默认值(默认值是Hash,基本上可以使用attr_accessor s之类的方法访问哈希键)。换句话说,我真的希望能够写obj.my_json_property来访问数据。
attr_accessor
obj.my_json_property
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/)。
object_class: Struct
Hash#[]
Hash#fetch
ljsrvy3e2#
下面是一个将Hash转换为Struct的快速方法:
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需要一些明显的处理 * 我只是没有打扰这部分,因为它不是问题的一部分)
Array
v9tzhpje3#
使用Struct.new创建一个新类,并使用所需的访问器将其作为object_class传递给JSON.parse:
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"
3条答案
按热度按时间xytpbqjk1#
如果OpenStruct是可接受的(这仍然可以将结构体用作
obj.my_json_property
,即它满足原始要求),使用这种方法:我尝试使用
object_class: Struct
,但它给了我“TypeError:分配器未定义的结构”。然而,对于 * 大多数 *(但不是全部)实际用途,OpenStruct就很好。主要的缺点是,如果你拼错了一个属性名,你的代码运行得很好,值将只是nil/空字符串(取决于上下文)。这可能有点烦人和误导。这有点像
Hash#[]
与Hash#fetch
(参考,请参阅:http://devblog.avdi.org/2009/03/16/go-fetch/)。ljsrvy3e2#
下面是一个将
Hash
转换为Struct
的快速方法:然后你可以做这样的事情:
在你的例子中:
可以很好地工作,它也可以处理嵌套对象(
Array
需要一些明显的处理 * 我只是没有打扰这部分,因为它不是问题的一部分)v9tzhpje3#
使用
Struct.new
创建一个新类,并使用所需的访问器将其作为object_class
传递给JSON.parse
: