我有一个看起来像这样的散列:
{ :a => "some string", :b => "another string", :c => "yet another string" }
我最终不想调用 to_json
,但生成的 json 字符串不能长于 n
字节。
如果字符串太大,那么先截断:c
。如果这还不够,:b
应该被截断。最后 :a
。此外,字符串可以包含多字节字符,如德语变音符号,Ruby 版本为 1.8.7。 (变音符号首先占用 2 个字节,但作为 json,它们的长度为 5 个字节。)
我写的是一个将散列转换为_json 并检查长度的循环。如果它小于或等于 n
它被返回,否则我连接 :a
+ :b
+ :c
并缩短一半。如果新哈希太大(小),我将缩短(扩展)原始字符串的 1/4、1/8、1/16。最后我得到了 hash.as_json == n
的长度。
这一切都让人感觉非常骇人听闻,尽管所有测试都通过了检查,但我不确定它是否稳定。
有没有人对如何正确解决这个问题有好的建议?
最佳答案
怎么样:
# encoding:UTF-8
require 'rubygems'
require 'json'
def constrained_json(limit, a, b, c)
output, size, hash = nil, 0, { :a => a, :b => b, :c => c}
[:c, :b, :a, :a].each do |key|
output = hash.to_json
size = output.bytesize
break if size <= limit
# on 1.9:
# hash[key] = hash[key][0...(limit - size)]
# on 1.8.7
hash[key] = hash[key].unpack("U*")[0...(limit - size)].pack("U*")
end
raise "Size exceeds limit even after truncation" if size > limit
output
end
38.downto(21) do |length|
puts "# #{constrained_json(length, "Qué te", "parece", "eh?")}"
end
# {"a":"Qué te","b":"parece","c":"eh?"}
# {"a":"Qué te","b":"parece","c":"eh"}
# {"a":"Qué te","b":"parece","c":"e"}
# {"a":"Qué te","b":"parece","c":""}
# {"a":"Qué te","b":"parec","c":""}
# {"a":"Qué te","b":"pare","c":""}
# ...
# {"a":"","b":"","c":""}
# test.rb:14:in `constrained_json': Size exceeds limit even after truncation (RuntimeError)
关于ruby - 如何截断哈希中的数据以使生成的 JSON 不超过 n 个字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6777987/