1

I want to normalise a Hash's keys using a normalisation function so that this hash

{"aType" => 1, "b_Type" => 2}

would be converted to

{:atype => 1, :btype => 2}

Here, the normalisation function removes underscores from the keys, downcases them, and makes them symbols.

I wrote the following using map (assume normalize is a normalisation method):

params = params.map {|k,v| {normalize(k) => v}}.inject(:merge)

Is there any better way to do this?

This question is related to a question "How to replace all hash keys having a '.'?". I want to know the optimal (less verbose or faster) way to do this.

Community
  • 1
  • 1
shigeya
  • 4,862
  • 3
  • 32
  • 33

3 Answers3

3

Here is how I would do it

Hash[h.map {|k,v| [normalize(k), v] }]
Alex.Bullard
  • 5,533
  • 2
  • 25
  • 32
  • Right, looks faster (I don't like `inject(:merge)` on performance point of view. Let me wait for other answers:) – shigeya Dec 18 '13 at 00:04
1

Here's how Rails does it (they extend Hash to make all keys strings in this case, but you could as easily put the method elsewhere).

def stringify_keys!
  keys.each do |key|
    self[key.to_s] = delete(key)
  end
  self
end

Though all of these approaches are reasonable, and there is likely not a substantial readability or performance difference for most uses.

Jeremy Roman
  • 16,137
  • 1
  • 43
  • 44
  • This sounds great, if I use same in various locations and monkey-patching `Hash` is reasonable. Great answer. Unfortunately, For my current project, I need to avoid monkey patching and need 'in place' or one-liner solution, so I can't use this way:< Let me decide which is the best answer later.. (regardless of whether I use the answer for my current project or not:) – shigeya Dec 18 '13 at 00:13
  • 2
    It's reasonably clear how you could use this method without monkey-patching. Just make it take an argument and use that in the place of `self` (and call `delete` on it). But no, it's not a one-liner. – Jeremy Roman Dec 18 '13 at 00:57
  • Thank you. Code itself is not a issue. Where to place the monkey-patching code is the issue, especially I only need this functionality at one place. – shigeya Dec 18 '13 at 11:33
0

If you are in a Rails application, or want to bring in ActiveSupport, you can use ActiveSupport::HashWithIndifferentAccess which allows you to use either 'key' or :key to set or get a value from the hash

Dan McClain
  • 11,780
  • 9
  • 47
  • 67
  • Thank you. I'm developing a rails application. But I need keys to be same in various locations (not only the hash itself) so I can't use this scheme. thanks anyway. – shigeya Dec 18 '13 at 00:14