ハッシュを取得する条件があります
hash = {"_id"=>"4de7140772f8be03da000018", .....}
そして私はこのハッシュを
hash = {"id"=>"4de7140772f8be03da000018", ......}
PS:ハッシュのキーが何なのかわからない、それらはランダムであり、すべてのキーに「_」プレフィックスが付いており、アンダースコアは必要ない
ハッシュを取得する条件があります
hash = {"_id"=>"4de7140772f8be03da000018", .....}
そして私はこのハッシュを
hash = {"id"=>"4de7140772f8be03da000018", ......}
PS:ハッシュのキーが何なのかわからない、それらはランダムであり、すべてのキーに「_」プレフィックスが付いており、アンダースコアは必要ない
回答:
hash[:new_key] = hash.delete :old_key
hash.delete :old_key
返される値から値を取得し、削除では古いキーを使用します。うわー、私はそれがどこかに入れ墨をしたいです:-Dありがとう
rails Hashには標準の方法があります。
hash.transform_keys{ |key| key.to_s.upcase }
http://api.rubyonrails.org/classes/Hash.html#method-i-transform_keys
UPD:ruby 2.5メソッド
すべてのキーが文字列で、すべてにアンダースコアのプレフィックスが付いている場合は、次のようにしてハッシュを適切な場所にパッチできます。
h.keys.each { |k| h[k[1, k.length - 1]] = h[k]; h.delete(k) }
の k[1, k.length - 1]
ビットのすべてをつかむk
最初の文字を除いて。コピーが必要な場合:
new_h = Hash[h.map { |k, v| [k[1, k.length - 1], v] }]
または
new_h = h.inject({ }) { |x, (k,v)| x[k[1, k.length - 1]] = v; x }
あなたも使うことができます sub
k[]
部分文字列を抽出するための表記法が気に入らない場合にできます。
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 }
また、一部のキーにのみアンダースコアのプレフィックスが付いている場合:
h.keys.each do |k|
if(k[0,1] == '_')
h[k[1, k.length - 1]] = h[k]
h.delete(k)
end
end
上記の他のすべてのバリアントに対して同様の変更を行うことができますが、次の2つがあります。
Hash[h.map { |k, v| [k.sub(/\A_/, ''), v] }]
h.inject({ }) { |x, (k,v)| x[k.sub(/\A_/, '')] = v; x }
追加の変更を行わずにアンダースコアのプレフィックスを持たないキーでも問題ありません。
できるよ
hash.inject({}){|option, (k,v) | option["id"] = v if k == "_id"; option}
これはあなたのケースでうまくいくはずです!
ハッシュ内の特定のキーの名前を変更する場合は、次のように変更できます。
私のハッシュが my_hash = {'test' => 'ruby hash demo'}
「test」を「message」に置き換えたい場合は、次のようにします
。
my_hash['message'] = my_hash.delete('test')
hash[:new_key] = has[:old_key]
ではなく、代わりに:ですhash[:dynamic_key] = hash[:_dynamic_key]
。これは、単純なハッシュ置換ではなく、正規表現に関する明確な質問でした。
h.inject({}) { |m, (k,v)| m[k.sub(/^_/,'')] = v; m }
私はやりすぎになり、次のことを思いつきました。これの背後にある私の動機は、ハッシュキーに追加して、一緒にマージ/ハッシュをフラット化するときにスコープの競合を回避することでした。
キー再生成メソッドをハッシュインスタンスに追加します。
# 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?!"}
ハッシュを渡してキーを再生成すると、ハッシュがマージされ、コレクションをフラット化できます。これにより、ハッシュをフラット化するときにキーにスコープを追加して、マージ時にキーを上書きしないようにすることができます。
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"}
# ]
# }
以前の回答で十分ですが、元のデータが更新される可能性があります。元のデータに影響を与えたくない場合は、私のコードを試すことができます。
newhash=hash.reject{|k| k=='_id'}.merge({id:hash['_id']})
最初にキー「_id」を無視して、更新されたキーとマージします。