Cómo reemplazar una clave hash con otra clave
Tengo una condición donde, obtengo un hash
hash = {"_id"=>"4de7140772f8be03da000018", .....}
Y quiero este hash como
hash = {"id"=>"4de7140772f8be03da000018", ......}
P. S : No se cuáles son las claves en el hash, son aleatorias que vienen con un prefijo " _ " para cada clave y no quiero guiones bajos
8 answers
Si todas las claves son cadenas y todas ellas tienen el prefijo de subrayado, entonces puede parchear el hash en su lugar con esto:
h.keys.each { |k| h[k[1, k.length - 1]] = h[k]; h.delete(k) }
El k[1, k.length - 1]
bit agarra todo k
excepto el primer carácter. Si quieres una copia, entonces:
new_h = Hash[h.map { |k, v| [k[1, k.length - 1], v] }]
O
new_h = h.inject({ }) { |x, (k,v)| x[k[1, k.length - 1]] = v; x }
También puedes usar sub
si no te gusta la notación k[]
para extraer una subcadena:
h.keys.each { |k| h[k.sub(/\A_/, '')] = h[k]; h.delete(k) }
Hash[h.map { |k, v| [k.sub(/\A_/, ''), v] }]
h.inject({ }) { |x, (k,v)| x[k.sub(/\A_/, '')] = v; x }
Y, si solo algunas de las claves tienen el subrayado prefijo:
h.keys.each do |k|
if(k[0,1] == '_')
h[k[1, k.length - 1]] = h[k]
h.delete(k)
end
end
Se pueden hacer modificaciones similares a todas las otras variantes anteriores, pero estas dos:
Hash[h.map { |k, v| [k.sub(/\A_/, ''), v] }]
h.inject({ }) { |x, (k,v)| x[k.sub(/\A_/, '')] = v; x }
Debería estar bien con las claves que no tienen prefijos de subrayado sin modificaciones adicionales.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-17 17:34:40
hash[:new_key] = hash.delete :old_key
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-10 14:22:50
Rails Hash tiene un método estándar para ello:
hash.transform_keys{ |key| key.to_s.upcase }
Http://api.rubyonrails.org/classes/Hash.html#method-i-transform_keys
UPD: método ruby 2.5
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-11 15:21:09
Puedes hacer
hash.inject({}){|option, (k,v) | option["id"] = v if k == "_id"; option}
Esto debería funcionar para su caso!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-02 05:11:39
h.inject({}) { |m, (k,v)| m[k.sub(/^_/,'')] = v; m }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-02 05:33:17
Si queremos cambiar el nombre de una clave específica en hash, podemos hacerlo de la siguiente manera:
Supongamos que mi hash es my_hash = {'test' => 'ruby hash demo'}
Ahora quiero reemplazar 'prueba' por 'mensaje', entonces: my_hash['message'] = my_hash.delete('test')
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-07 11:10:58
hash.each {|k,v| hash.delete(k) && hash[k[1..-1]]=v if k[0,1] == '_'}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-02 05:36:03
En las versiones de Ruby > = 2.5, puede usar Hash # transform_keys método
hash.transform_keys {|k| k.sub(/\A_/, '') }
# => { "id" => "4de7140772f8be03da000018" }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-26 06:43:36