Comment remplacer toutes les clés d'un hachage par un nouvel ensemble de clés données ?
Existe-t-il un moyen de le faire de manière élégante ?
Comment remplacer toutes les clés d'un hachage par un nouvel ensemble de clés données ?
Existe-t-il un moyen de le faire de manière élégante ?
Vous êtes l'homme de la situation ! Votre hachage est tout à fait génial ! Merci encore pour ce bijou ! :)
Il suppose également que vous avez key_map
défini comme un hachage de paires clé/valeur où la clé est l'ancienne clé et la valeur est la nouvelle clé qui est échangée.
Ruby 2.5 a Hash#transform_keys ! méthode. Exemple d'utilisation d'une carte de clés
h = {a: 1, b: 2, c: 3}
key_map = {a: 'A', b: 'B', c: 'C'}
h.transform_keys! {|k| key_map[k]}
# => {"A"=>1, "B"=>2, "C"=>3}
Vous pouvez également utiliser le raccourci symbol#toproc avec transform_keys Eg :
h.transform_keys! &:upcase
# => {"A"=>1, "B"=>2, "C"=>3}
Je suppose que vous souhaitez modifier le hachage keys
sans modifier les valeurs :
hash = {
"nr"=>"123",
"name"=>"Herrmann Hofreiter",
"pferd"=>"010 000 777",
"land"=>"hight land"
}
header = ["aa", "bb", "cc", "dd"]
new_hash = header.zip(hash.values).to_h
Résultat :
{
"aa"=>"123",
"bb"=>"Herrmann Hofreiter",
"cc"=>"010 000 777",
"dd"=>"high land"
}
Une autre façon de procéder est la suivante :
hash = {
'foo' => 1,
'bar' => 2
}
new_keys = {
'foo' => 'foozle',
'bar' => 'barzle'
}
new_keys.values.zip(hash.values_at(*new_keys.keys)).to_h
# => {"foozle"=>1, "barzle"=>2}
La décomposition :
new_keys
.values # => ["foozle", "barzle"]
.zip(
hash.values_at(*new_keys.keys) # => [1, 2]
) # => [["foozle", 1], ["barzle", 2]]
.to_h
# => {"foozle"=>1, "barzle"=>2}
C'est l'heure du bilan...
Bien que j'apprécie la simplicité de la réponse de Jörn, je n'étais pas sûr qu'elle soit aussi rapide qu'elle devrait l'être, puis j'ai vu le commentaire de selvamani :
require 'fruity'
HASH = {
'foo' => 1,
'bar' => 2
}
NEW_KEYS = {
'foo' => 'foozle',
'bar' => 'barzle'
}
compare do
mittag { HASH.dup.map {|k, v| [NEW_KEYS[k], v] }.to_h }
ttm { h = HASH.dup; NEW_KEYS.values.zip(h.values_at(*NEW_KEYS.keys)).to_h }
selvamani { h = HASH.dup; h.keys.each { |key| h[NEW_KEYS[key]] = h.delete(key)}; h }
end
# >> Running each test 2048 times. Test will take about 1 second.
# >> selvamani is faster than ttm by 39.99999999999999% ± 10.0%
# >> ttm is faster than mittag by 10.000000000000009% ± 10.0%
Les vitesses sont très proches les unes des autres, donc n'importe laquelle fera l'affaire, mais 39% est rentable sur le long terme, alors tenez-en compte. Quelques réponses n'ont pas été incluses parce qu'il y a des failles potentielles où elles donneraient de mauvais résultats.
La solution exacte dépend du format dans lequel vous avez les nouvelles clés (ou si vous pouvez dériver la nouvelle clé de l'ancienne).
En supposant que vous disposiez d'un hachage h
dont vous souhaitez modifier les clés et un hash new_keys
qui associe les clés actuelles aux nouvelles clés que vous pourriez utiliser :
h.keys.each do |key|
h[new_keys[key]] = h[key] # add entry for new key
k.delete(key) # remove old key
end
Cela supprimera une valeur pour key
quand new_keys
se retrouve accidentellement à renvoyer key
pour un certain nombre de key
. la réponse de barbolos à cette question : stackoverflow.com/questions/4137824 permet de surmonter ce problème.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.