I am using Ruby on Rails 4 and I would like to replace all hash keys so to change the hash from
h_before = {:"aaa.bbb" => 1, :c => 2, ...}
to
h_after = {:bbb => 1, :c => 2, ...}
That is, I would like to someway "demodulize" all hash keys having the .
. How can I make that?
Since there are a bunch of answers claiming to do the same thing, I thought it was time to post some benchmarks:
Which outputs:
Notice that phlip's code doesn't return the desired results.
each_with_object is a cleaner and shorter approach than inject from the answer:
My
grep_keys
has never failed me here:It returns a shallow-copy of the Hash, but only with the matched keys. If the input regular expression contains a
()
match, the method replaces the key with the matched value. (Note this might merge two or more keys, and discard all but a random value for them!) I use it all the time to cut up a Railsparam
into sub-params containing only the keys that some module needs.{:"aaa.bbb" => 1, :c => 2 }.grep_keys(/\.(\w+)$/)
returns{"bbb"=>1}
.This method upgrades your actual problem to "how to define a regexp that matches what you mean by 'having a ".".'"