我想了解在使用Oj解析JSON文件时如何理解在每个键上应用转换(在我的情况下是下划线)的方法。
例如在ruby / rails中:
require 'oj'
Oj.optimize_rails()
def transform_keys(hash)
hash.deep_transform_keys { |k| k.to_s.underscore }
end
data = '{ "JsonKey": "JsonValue", "JsonKey2": { "JsonSubKey2": "JsonSubValue" }, "Array": ["ValueArray1","ValueArray2"] }'
data2 = '[{ "JsonKey": "JsonValue", "JsonKey2": { "JsonSubKey2": "JsonSubValue" }, "Array": ["ValueArray1","ValueArray2"] }]'
json_data = JSON.parse(data)
case json_data
when Hash
transform_keys(json_data)
when Array
json_data.map { |hash| transform_keys(hash) }
end
这可以完成这项任务,但它会迭代两次:一次解析并应用转换。
检查oj,我发现:
试试吧:
class UnderscoreKeyHandler < ::Oj::ScHandler
def hash_start
{}
end
def hash_set(h,k,v)
h[k.to_s.underscore] = v
end
def array_start
[]
end
def array_append(a,v)
a << v
end
def add_value(v)
end
end
handler = UnderscoreKeyHandler.new
Oj.sc_parse(handler, data)
有效!好吧,让我们对此进行基准测试:
require 'oj'
Oj.optimize_rails()
hash = Hash.new
key = 'abcd'
1000.times { hash[key.succ!] = hash.keys }
json = hash.to_json; nil
def transform_keys(hash)
hash.deep_transform_keys { |k| k.to_s.underscore }
end
10000 * Benchmark.realtime {
json_data = JSON.parse(json)
case json_data
when Hash
transform_keys(json_data)
when Array
json_data.map { |hash| transform_keys(hash) }
end
} # Between 2400 and 3500
10000 * Benchmark.realtime { Oj.sc_parse(handler, json) } # Between 700 and 1600
完美?我似乎是,但我感到不安全......
实际上我只想覆盖哈希的每个键而不是重写完整的处理程序。有办法吗?
此外: