Ich habe eine Bedingung, wo ich einen Hash bekomme
hash = {"_id"=>"4de7140772f8be03da000018", .....}
und ich möchte diesen Hash als
hash = {"id"=>"4de7140772f8be03da000018", ......}
P.S : Ich weiß nicht, was die Schlüssel im Hash sind, sie sind zufällig, was mit einem "_" - Präfix für jeden Schlüssel kommt und ich möchte keine Unterstriche
Wenn alle Schlüssel Strings sind und alle das Unterstrich-Präfix haben, können Sie den Hash mit folgendem Patch aktualisieren:
h.keys.each { |k| h[k[1, k.length - 1]] = h[k]; h.delete(k) }
Das k[1, k.length - 1]
- Bit erfasst alle Variablen von k
mit Ausnahme des ersten Zeichens. Wenn Sie eine Kopie wünschen, dann:
new_h = Hash[h.map { |k, v| [k[1, k.length - 1], v] }]
Oder
new_h = h.inject({ }) { |x, (k,v)| x[k[1, k.length - 1]] = v; x }
Sie können auch sub
verwenden, wenn Sie die k[]
-Notation nicht für das Extrahieren eines Teilstrings mögen:
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 }
Und wenn nur einige der Schlüssel das Unterstrich-Präfix haben:
h.keys.each do |k|
if(k[0,1] == '_')
h[k[1, k.length - 1]] = h[k]
h.delete(k)
end
end
Ähnliche Modifikationen können an allen anderen oben genannten Varianten vorgenommen werden, außer diesen beiden:
Hash[h.map { |k, v| [k.sub(/\A_/, ''), v] }]
h.inject({ }) { |x, (k,v)| x[k.sub(/\A_/, '')] = v; x }
sollte mit Schlüsseln, die keine Unterstriche ohne zusätzliche Modifikationen enthalten, in Ordnung sein.
hash[:new_key] = hash.delete :old_key
Rails Hash hat eine Standardmethode dafür:
hash.transform_keys{ |key| key.to_s.upcase }
http://api.rubyonrails.org/classes/Hash.html#method-i-transform_keys
UPD: Ruby 2.5-Methode
du kannst tun
hash.inject({}){|option, (k,v) | option["id"] = v if k == "_id"; option}
Das sollte für Ihren Fall funktionieren!
h.inject({}) { |m, (k,v)| m[k.sub(/^_/,'')] = v; m }
Wenn wir einen bestimmten Schlüssel in Hash umbenennen möchten, können wir dies wie folgt tun:
Angenommen, mein Hash ist my_hash = {'test' => 'Ruby hash demo'}
Nun möchte ich 'test' durch 'message' ersetzen, dann:my_hash['message'] = my_hash.delete('test')
hash.each {|k,v| hash.delete(k) && hash[k[1..-1]]=v if k[0,1] == '_'}
Ich bin übertrieben und habe mir folgendes ausgedacht. Meine Motivation dahinter war, an Hash-Schlüssel anzuhängen, um beim Zusammenführen/Reduzieren von Hashes Konflikte zu vermeiden.
Fügt den Hash-Instanzen eine rekey-Methode hinzu.
# Adds additional methods to Hash
class ::Hash
# Changes the keys on a hash
# Takes a block that passes the current key
# Whatever the block returns becomes the new key
# If a hash is returned for the key it will merge the current hash
# with the returned hash from the block. This allows for nested rekeying.
def rekey
self.each_with_object({}) do |(key, value), previous|
new_key = yield(key, value)
if new_key.is_a?(Hash)
previous.merge!(new_key)
else
previous[new_key] = value
end
end
end
end
my_feelings_about_icecreams = {
Vanilla: 'Delicious',
chocolate: 'Too Chocolatey',
strawberry: 'It Is Alright...'
}
my_feelings_about_icecreams.rekey { |key| "#{key}_icecream".to_sym }
# => {:Vanilla_icecream=>"Delicious", :chocolate_icecream=>"Too Chocolatey", :strawberry_icecream=>"It Is Alright..."}
{ _id: 1, ___something_: 'what?!' }.rekey do |key|
trimmed = key.to_s.tr('_', '')
trimmed.to_sym
end
# => {:id=>1, :something=>"what?!"}
Wenn Sie einen Hash zurückgeben, um ihn erneut zu verschlüsseln, wird der Hash zusammengeführt, sodass Sie Sammlungen reduzieren können. Auf diese Weise können wir beim Reduzieren eines Hashs einen Bereich zu unseren Schlüsseln hinzufügen, um das Überschreiben eines Schlüssels beim Zusammenführen zu vermeiden.
people = {
bob: {
name: 'Bob',
toys: [
{ what: 'car', color: 'red' },
{ what: 'ball', color: 'blue' }
]
},
tom: {
name: 'Tom',
toys: [
{ what: 'house', color: 'blue; da ba dee da ba die' },
{ what: 'nerf gun', color: 'metallic' }
]
}
}
people.rekey do |person, person_info|
person_info.rekey do |key|
"#{person}_#{key}".to_sym
end
end
# =>
# {
# :bob_name=>"Bob",
# :bob_toys=>[
# {:what=>"car", :color=>"red"},
# {:what=>"ball", :color=>"blue"}
# ],
# :tom_name=>"Tom",
# :tom_toys=>[
# {:what=>"house", :color=>"blue; da ba dee da ba die"},
# {:what=>"nerf gun", :color=>"metallic"}
# ]
# }