해시를 얻는 조건이 있습니다.
hash = {"_id"=>"4de7140772f8be03da000018", .....}
이 해시를
hash = {"id"=>"4de7140772f8be03da000018", ......}
추신 : 해시의 키가 무엇인지 모르겠습니다. 키마다 임의의 "_"접두사가 붙어 무작위로 밑줄을 원하지 않습니다.
해시를 얻는 조건이 있습니다.
hash = {"_id"=>"4de7140772f8be03da000018", .....}
이 해시를
hash = {"id"=>"4de7140772f8be03da000018", ......}
추신 : 해시의 키가 무엇인지 모르겠습니다. 키마다 임의의 "_"접두사가 붙어 무작위로 밑줄을 원하지 않습니다.
답변:
hash[:new_key] = hash.delete :old_key
hash.delete :old_key
리턴 된 값에서 값을 가져 오면 삭제는 이전 키를 사용합니다. 와우, 나는 어딘가에 문신을하고 싶다 : -D Thanks
레일 해시는 표준 방법을 가지고 있습니다 :
hash.transform_keys{ |key| key.to_s.upcase }
http://api.rubyonrails.org/classes/Hash.html#method-i-transform_keys
UPD : 루비 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
위의 다른 모든 변형에 대해 유사한 수정을 수행 할 수 있지만 다음 두 가지가 있습니다.
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'키를 무시한 다음 업데이트 된 키와 병합합니다.