Comment remplacer une clé de hachage par une autre clé
J'ai une condition où, je reçois un hachage
hash = {"_id"=>"4de7140772f8be03da000018", .....}
Et je veux ce hachage comme
hash = {"id"=>"4de7140772f8be03da000018", ......}
P. S : Je ne sais pas quelles sont les clés dans le hachage, elles sont aléatoires qui vient avec un préfixe " _ " pour chaque clé et je ne veux pas de soulignement
8 réponses
Si toutes les clés sont des chaînes et toutes ont le préfixe de soulignement, alors vous pouvez patcher le hachage en place avec ceci:
h.keys.each { |k| h[k[1, k.length - 1]] = h[k]; h.delete(k) }
Le k[1, k.length - 1]
peu de s'approprier la totalité de k
, sauf le premier caractère. Si vous voulez une copie, alors:
new_h = Hash[h.map { |k, v| [k[1, k.length - 1], v] }]
Ou
new_h = h.inject({ }) { |x, (k,v)| x[k[1, k.length - 1]] = v; x }
Vous pouvez également utiliser sub
si vous n'aimez pas la k[]
notation pour l'extraction d'une sous-chaîne:
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 }
Et, si seulement certaines des clés ont le trait de soulignement préfixe:
h.keys.each do |k|
if(k[0,1] == '_')
h[k[1, k.length - 1]] = h[k]
h.delete(k)
end
end
Des modifications similaires peuvent être faites à toutes les autres variantes ci-dessus, mais ces deux:
Hash[h.map { |k, v| [k.sub(/\A_/, ''), v] }]
h.inject({ }) { |x, (k,v)| x[k.sub(/\A_/, '')] = v; x }
Devrait être d'accord avec les clés qui n'ont pas de préfixes de soulignement sans modifications supplémentaires.
Rails Hash a une méthode standard pour cela:
hash.transform_keys{ |key| key.to_s.upcase }
Http://api.rubyonrails.org/classes/Hash.html#method-i-transform_keys
UPD: Ruby 2.5 méthode
Vous pouvez faire
hash.inject({}){|option, (k,v) | option["id"] = v if k == "_id"; option}
Cela devrait fonctionner pour votre cas!
Si nous voulons renommer la clé de hachage alors nous pouvons le faire comme suit:
supposons que mon hachage soit my_hash = {'test' => 'ruby hash demo'}
Maintenant, je veux remplacer "test" par "message", puis: my_hash['message'] = my_hash.delete('test')
hash.each {|k,v| hash.delete(k) && hash[k[1..-1]]=v if k[0,1] == '_'}
Dans les versions Ruby > = 2.5, vous pouvez utiliser Hash # transform_keys Méthode
hash.transform_keys {|k| k.sub(/\A_/, '') }
# => { "id" => "4de7140772f8be03da000018" }