« Back to Index

Convert Ruby Hash keys into symbols

View original Gist on GitHub

Hash Keys to Symbols.rb

hash = { 'foo' => 'bar' }

# Version 1
hash = Hash[hash.map { |k, v| [k.to_sym, v] }]

# Version 2
hash = hash.reduce({}) do |memo, (k, v)| 
  memo.tap { |m| m[k.to_sym] = v }
end

# Version 3
hash = hash.reduce({}) do |memo, (k, v)| 
  memo.merge({ k.to_sym => v})
end

# None of the above solutions work with a multi-level hash
# They only work on the first level: {:foo=>"bar", :level1=>{"level2"=>"baz"}}
# The following two variations solve the problem in the same way

multi_hash = { 'foo' => 'bar', 'level1' => { 'level2' => 'baz' } }

# Modify `Object`
class Object
  def deep_symbolize_keys
    return self.reduce({}) do |memo, (k, v)|
      memo.tap { |m| m[k.to_sym] = v.deep_symbolize_keys }
    end if self.is_a? Hash
    
    return self.reduce([]) do |memo, v| 
      memo << v.deep_symbolize_keys; memo
    end if self.is_a? Array
    
    self
  end
end

multi_hash = multi_hash.deep_symbolize_keys

# Standalone method
def symbolize(obj)
  return obj.reduce({}) do |memo, (k, v)|
    memo.tap { |m| m[k.to_sym] = symbolize(v) }
  end if obj.is_a? Hash
    
  return obj.reduce([]) do |memo, v| 
    memo << symbolize(v); memo
  end if obj.is_a? Array
  
  obj
end

multi_hash = symbolize(multi_hash)