How to truncate data in a hash so that the resulting JSON isn't longer than n bytes?

两盒软妹~` 提交于 2019-12-24 01:46:16

问题


I have a hash that looks something like this:

{ :a => "some string", :b => "another string", :c => "yet another string" }

I wan't to call to_jsonon it eventually, but the resulting json-string cannot be longer than n bytes.

If the string is too big, then first :c should be truncated first. If that's not enough, :b should be truncated. Finally :a. Also the strings can contain multi-byte characters like German umlauts and the Ruby version is 1.8.7. (The umlauts first take 2 bytes, but as json they are 5 bytes long.)

What I wrote was a loop that converts the hash to_json and checks the length. If its less or equal n it's returned, otherwise I concat the values of :a + :b + :c and shorten by half. If the new hash is too big(small), I shorten(extend) by 1/4th, 1/8th, 1/16th of the original string. Finally I get length of hash.as_json == n.

It all feels very hackish and although all tests check out I'm not sure that's even stable.

Does anyone have a good suggestion how to solve this properly?


回答1:


How about:

# 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)


来源:https://stackoverflow.com/questions/6777987/how-to-truncate-data-in-a-hash-so-that-the-resulting-json-isnt-longer-than-n-by

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!