Skip to content

Instantly share code, notes, and snippets.

@mkuhnt
Last active October 6, 2021 12:48
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mkuhnt/6815250 to your computer and use it in GitHub Desktop.
Save mkuhnt/6815250 to your computer and use it in GitHub Desktop.
Deep Stringify Keys of hash even with embedded arrays
def transform_hash(original, options={}, &block)
original.inject({}){|result, (key,value)|
value = if (options[:deep] && Hash === value)
transform_hash(value, options, &block)
else
if Array === value
value.map{|v| transform_hash(v, options, &block)}
else
value
end
end
block.call(result,key,value)
result
}
end
# Convert keys to strings
def stringify_keys(hash)
transform_hash(hash) {|hash, key, value|
hash[key.to_s] = value
}
end
# Convert keys to strings, recursively
def deep_stringify_keys(hash)
transform_hash(hash, :deep => true) {|hash, key, value|
hash[key.to_s] = value
}
end
h1 = {a: {b: "c", d: [{a: "test", b: "test 2"},{a: "test 3"}]}}
puts h1
puts stringify_keys(h1)
puts deep_stringify_keys(h1)
@mkuhnt
Copy link
Author

mkuhnt commented Oct 3, 2013

@BananaNeil
Copy link

I was trying to do this today, and I was pretty excited about my solution:

require 'json'

h1 = {a: {b: "c", d: [{a: "test", b: "test 2"},{a: "test 3"}]}}

puts JSON[h1.to_json]
=> {"a"=>{"b"=>"c", "d"=>[{"a"=>"test", "b"=>"test 2"}, {"a"=>"test 3"}]}}

Copy link

ghost commented Feb 11, 2017

Made little changes now works for cases where there are strings/numbers/other in hash arrays.

h1 = {:a=>{:b=>"c", :d=>[{:a=>"test", :b=>"test 2"}, {:a=>"test 3"}, "string1"], :e=>["string2"]}}
HashUtils.deep_stringify_keys(h1)
output: {"a"=>{"b"=>"c", "d"=>[{"a"=>"test", "b"=>"test 2"}, {"a"=>"test 3"}, "string1"], "e"=>[1]}}

h2 = {:a=>{:b=>"c", :d=>[{:a=>"test", :b=>"test 2"}, {:a=>"test 3"}, "string1"], :e=>[1]}}
HashUtils.deep_stringify_keys(h2)
output :  {"a"=>{"b"=>"c", "d"=>[{"a"=>"test", "b"=>"test 2"}, {"a"=>"test 3"}, "string1"], "e"=>[1]}}
class HashUtils
  def self.transform_hash(original, options={}, &block)
    original.inject({}){|result, (key,value)|
      value = if (options[:deep] && Hash === value)
                transform_hash(value, options, &block)
              else
                if Array === value
                  value.map{|v|
                    if Hash === v
                      transform_hash(v, options, &block)
                    else
                      v
                    end}
                else
                  value
                end
              end
      block.call(result,key,value)
      result
    }
  end
  # Convert keys to strings, recursively
  def self.deep_stringify_keys(hash)
    transform_hash(hash, :deep => true) {|hash, key, value|
      hash[key.to_s] = value
    }
  end
end
  block.call(result,key,value)
      result
    }
  end
  # Convert keys to strings, recursively
  def self.deep_stringify_keys(hash)
    transform_hash(hash, :deep => true) {|hash, key, value|
      hash[key.to_s] = value
    }
  end
end

@laurajaime
Copy link

I was trying to do this today, and I was pretty excited about my solution:

require 'json'

h1 = {a: {b: "c", d: [{a: "test", b: "test 2"},{a: "test 3"}]}}

puts JSON[h1.to_json]
=> {"a"=>{"b"=>"c", "d"=>[{"a"=>"test", "b"=>"test 2"}, {"a"=>"test 3"}]}}

So great!!!! thanks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment