ruby-on-rails - new - ruby fr




Comment remplacer une clé de hachage avec une autre clé (5)

J'ai une condition où, je reçois un hachage

  hash = {"_id"=>"4de7140772f8be03da000018", .....}

et je veux ce hash comme

  hash = {"id"=>"4de7140772f8be03da000018", ......}

PS : Je ne sais pas quelles sont les clés dans le hachage, elles sont aléatoires qui vient avec un préfixe "_" pour chaque touche et je ne veux pas de traits de soulignement


Si nous voulons renommer une clé spécifique en hachage, nous pouvons le faire comme suit:
Supposons que mon hash soit my_hash = {'test' => 'ruby hash demo'}
Maintenant, je veux remplacer «test» par «message», puis:
my_hash['message'] = my_hash.delete('test')


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 bit k[1, k.length - 1] saisit tout le 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 aussi utiliser sub si vous n'aimez pas la notation k[] pour extraire 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 préfixe de soulignement:

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 apportées à toutes les autres variantes ci-dessus, mais ces deux-là:

Hash[h.map { |k, v| [k.sub(/\A_/, ''), v] }]
h.inject({ }) { |x, (k,v)| x[k.sub(/\A_/, '')] = v; x }

devrait être correct avec les touches qui n'ont pas de préfixes de soulignement sans modifications supplémentaires.


tu peux faire

hash.inject({}){|option, (k,v) | option["id"] = v if k == "_id"; option}

Cela devrait fonctionner pour votre cas!


h.inject({}) { |m, (k,v)| m[k.sub(/^_/,'')] = v; m }

hash[:new_key] = hash.delete :old_key




hash