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


i have hash looks this:

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

i wan't call to_jsonon eventually, resulting json-string cannot longer n bytes.

if string big, first :c should truncated first. if that's not enough, :b should truncated. :a. strings can contain multi-byte characters german umlauts , ruby version 1.8.7. (the umlauts first take 2 bytes, json 5 bytes long.)

what wrote loop converts hash to_json , checks length. if less or equal n it's returned, otherwise concat values of :a + :b + :c , shorten half. if new hash big(small), shorten(extend) 1/4th, 1/8th, 1/16th of original string. length of hash.as_json == n.

it feels hackish , although tests check out i'm not sure that's stable.

does have suggestion how solve properly?

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 |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 after truncation" if size > limit   output end  38.downto(21) |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 after truncation (runtimeerror) 

Comments

Popular posts from this blog

linux - Using a Cron Job to check if my mod_wsgi / apache server is running and restart -

actionscript 3 - TweenLite does not work with object -

jQuery Ajax Render Fragments OR Whole Page -