Given hash with nested documents:
myHash = {
"MemberId"=>"ABC0001",
"MemberName"=>"Alan",
"details"=>[
{"LineNumber"=>"4.1", "Item"=>"A0001", "Description"=>"Apple"},
{"LineNumber"=>"5.1", "Item"=>"A0002"},
{"LineNumber"=>"6.1", "Item"=>"Orange"}
]
}
I want to change it so it will look like:
{
"memberid"=>"ABC0001",
"membername"=>"Alan",
"details"=>[
{"linenumber"=>"4.1", "item"=>"A0001", "description"=>"Apple"},
{"linenumber"=>"5.1", "item"=>"A0002"},
{"linenumber"=>"6.1", "item"=>"Orange"}
]
}
In other words, I want to change to lower case if any in the hash key. I understand I'll have to iterate through the hash and use downcase method. If there any easy way of doing this in ruby?
Modifying hashes in Ruby: Hash can be modified by adding or deleting a key value/pair in an already existing hash. Also, you can change the existing value of key in the hash.
Ruby strings have methods to convert them to uppercase and lowercase. The method names of the methods are upcase and downcase respectively. Calling the downcase or upcase method on a string will return the lowercase or uppercase version of the string, but the original variable won't change.
Between curly braces {}, the key/value pairs are created. Fetching hash values: To fetch a hash value always put the required key within the square bracket []. Modifying hashes in Ruby: Hash can be modified by adding or deleting a key value/pair in an already existing hash. Also, you can change the existing value of key in the hash.
It’s a nicer syntax that allows you to create hashes without the hash-rocket ( =>) symbol, which is a valid, but older way to do it. Values can be any Ruby object. Keys can also be anything, but symbols (like :banana) & strings are the most common type of keys you’ll find.
You can simple do
hash.transform_keys(&:downcase)
to change hash keys to lowercase.
you can refer my answer https://stackoverflow.com/a/54090178/8247133
class Hash
def downcase_key
keys.each do |k|
store(k.downcase, Array === (v = delete(k)) ? v.map(&:downcase_key) : v)
end
self
end
end
myHash.downcase_key
def f h
Hash[h.map{|k,v| v.class == Array ? [k,v.map{|r| f r}.to_a] : [k.downcase,v]}]
end
proof
I would first create a method on Hash
that allows you to map the keys to new values:
class Hash
def map_keys! &blk
keys.each do |k|
new_k = blk.call(k)
self[new_k] = delete(k)
end
self
end
def map_keys &blk
dup.map_keys!(&blk)
end
end
You can now downcase the first level with
myHash.map_keys!(&:downcase)
myHash
now contains:
{"details"=>
[{"LineNumber"=>"4.1", "Item"=>"A0001", "Description"=>"Apple"},
{"LineNumber"=>"5.1", "Item"=>"A0002"},
{"LineNumber"=>"6.1", "Item"=>"Orange"}],
"memberid"=>"ABC0001",
"membername"=>"Alan"}
The nested hashes can be converted with
myHash['details'].each{|h| h.map_keys!(&:downcase) }
myHash
now contains:
{"details"=>
[{"linenumber"=>"4.1", "item"=>"A0001", "description"=>"Apple"},
{"linenumber"=>"5.1", "item"=>"A0002"},
{"linenumber"=>"6.1", "item"=>"Orange"}],
"memberid"=>"ABC0001",
"membername"=>"Alan"}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With