3

I've got a JSON string that I need to remove all the blank values from. Something like:

[{"body":"","user":"mike","id":1234567,"type":"","published_at":"2015-05-22T14:51:00-04:00","title":null,"updated_at":"2015-05-23T22:04:38-04:00","postoffice":"Testing","tags":"","variants":[{"value":"", "service":"canada post"}]}]

I've considered going through all the elements and testing if they're "", and I've also considered loading the JSON through JSON.load and having the proc option remove blanks (though I'm fairly new to Ruby and don't know how to do that).

What is the best way to recursively remove all blank values from a JSON string? (Note that in this example variants is only one level deep for simplification. In reality it can be many levels deep.)

For completeness, the end result should look like:

[{"user":"mike","id":1234567,"published_at":"2015-05-22T14:51:00-04:00","title":null,"updated_at":"2015-05-23T22:04:38-04:00","postoffice":"Testing","variants":[{"service":"canada post"}]}]

(null values are OK in my case).

Said Kaldybaev
  • 9,380
  • 8
  • 36
  • 53
Mike Potter
  • 35
  • 1
  • 6

3 Answers3

2
require 'json'

JSON.load(json, proc do |a|
  a.is_a?(Hash) && a.delete_if do |_k,v|
    next unless v.is_a?(String)
    v.empty?
  end
end

Result:

[{"user"=>"mike",
  "id"=>1234567,
  "published_at"=>"2015-05-22T14:51:00-04:00",
  "title"=>nil,
  "updated_at"=>"2015-05-23T22:04:38-04:00",
  "postoffice"=>"Testing",
  "variants"=>[{"service"=>"canada post"}]}]
iNulty
  • 923
  • 8
  • 17
1
require 'json'

json = JSON.parse(your_json)
json.first.reject! do |key, value|
  value == ''
end
puts json.to_s
Matt Gibson
  • 14,616
  • 7
  • 47
  • 79
0

Note I had to change null to nil so it would be a valid ruby hash. The result is a bit verbose but gets the job done:

def strip_empties(json)
  json.each_with_object([]) do |record, results|
    record.each do |key, value|
      if value.is_a? Array
        results << { key => strip_empties(value) }
      else
        results << { key => value } unless value == ""
      end
    end
  end
end

result = strip_empties(json)

Output with nil but no empty strings:

=> [{:user=>"mike"},
 {:id=>1234567},
 {:published_at=>"2015-05-22T14:51:00-04:00"},
 {:title=>nil},
 {:updated_at=>"2015-05-23T22:04:38-04:00"},
 {:postoffice=>"Testing"},
 {:variants=>[{:service=>"canada post"}]}]
Anthony
  • 15,435
  • 4
  • 39
  • 69
  • This is not isomorphic with respect to the original json object. The original json array had one object with many fields, this is one array with many hashes – iNulty Oct 13 '20 at 21:45
  • You're right @iNulty - I'll remove in favor of yours – Anthony Oct 13 '20 at 22:14
  • JSON deserialization is annoying me in ruby right now. This proc param of `JSON.load` is WAY under-documented. – iNulty Oct 13 '20 at 22:26