6

I have the following keys in my hash:

address, postcode

I want to add the "shipping_" prefix to each of them so they would become:

shipping_address, shipping_postcode

instead. How can I do this?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Fenec
  • 1,224
  • 13
  • 21
  • 2
    [This question](http://stackoverflow.com/questions/6210572/how-to-replace-a-hash-key-with-another-key) and [this question](http://stackoverflow.com/questions/4137824/how-to-elegantly-rename-all-keys-in-a-hash-in-ruby) on how to replace the keys in a hash might help you out. – James Chevalier Jul 17 '13 at 13:22

3 Answers3

9
hsh1 = {'address' => "foo", 'postcode' => "bar"}
hsh2 = Hash[hsh1.map{|k,v| [k.dup.prepend("shipping_"),v]}]
p hsh2
# >> {"shipping_address"=>"foo", "shipping_postcode"=>"bar"}

update

hsh1 = {'address' => "foo", 'postcode' => "bar"}
hsh2 = Hash[hsh1.map{|k,v| ["shipping_#{k}",v]}]
p hsh2
# >> {"shipping_address"=>"foo", "shipping_postcode"=>"bar"}
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
  • 3
    Instead of `k.dup.prepend("shipping_")` let Ruby handle the `dup.prepend` by using `"shipping_#{k}"`. It's more obvious what's going on. – the Tin Man Jul 17 '13 at 15:44
8

In Ruby >= 2.5, you can do

hsh.transform_keys! {|k| 'shipping_' + k }
# => {"shipping_address"=>"foo", "shipping_postcode"=>"bar"} 

And if you want to be fancy

hsh.transform_keys! &'shipping_'.method(:+)
# => {"shipping_address"=>"foo", "shipping_postcode"=>"bar"} 
Santhosh
  • 28,097
  • 9
  • 82
  • 87
4

If you want to do it destructively, this is a short way:

hash.keys.each{|k| hash.store("shipping_#{k}", hash.delete(k))}
sawa
  • 165,429
  • 45
  • 277
  • 381