해시 키를 다른 키로 대체하려면 어떻게 해야 합니까?
저는 해시에 걸리는 조건이 있습니다.
hash = {"_id"=>"4de7140772f8be03da000018", .....}
하지만 저는 그 해시의 키 이름을 다음과 같이 바꾸고 싶습니다.
hash = {"id"=>"4de7140772f8be03da000018", ......}
추신: 저는 해시에 어떤 키가 있는지 모릅니다. 그것들은 무작위입니다.일부 키에는 제거하려는 밑줄이 앞에 붙습니다.
hash[:new_key] = hash.delete :old_key
레일 해시에는 표준 방법이 있습니다.
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
첫 번째 문자를 제외합니다.복사본을 원하는 경우:
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 }
또한 당신이 마음에 들지 않는다면 사용할 수 있습니다.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')
transform_keys 및 delete_prefix/delete_suffix 메서드가 있는 Ruby 2.5 이상의 경우:
hash1 = { '_id' => 'random1' }
hash2 = { 'old_first' => '123456', 'old_second' => '234567' }
hash3 = { 'first_com' => 'google.com', 'second_com' => 'amazon.com' }
hash1.transform_keys { |key| key.delete_prefix('_') }
# => {"id"=>"random1"}
hash2.transform_keys { |key| key.delete_prefix('old_') }
# => {"first"=>"123456", "second"=>"234567"}
hash3.transform_keys { |key| key.delete_suffix('_com') }
# => {"first"=>"google.com", "second"=>"amazon.com"}
h.inject({}) { |m, (k,v)| m[k.sub(/^_/,'')] = v; m }
hash.each {|k,v| hash.delete(k) && hash[k[1..-1]]=v if k[0,1] == '_'}
저는 과잉 살상을 했고 다음과 같은 것들을 생각해냈습니다.이것의 배경이 된 동기는 해시를 병합/평평화할 때 범위 충돌을 방지하기 위해 해시 키를 추가하는 것이었습니다.
예
해시 클래스 확장
해시 인스턴스에 키 재생성 메서드를 추가합니다.
# 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?!"}
"Scope" 평탄화 및 추가
키 재생성을 위해 해시를 다시 전달하면 수집을 평탄화할 수 있는 해시가 병합됩니다.따라서 해시를 평탄화할 때 키에 범위를 추가하여 병합 시 키를 덮어쓰지 않도록 할 수 있습니다.
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' 키를 무시한 다음 업데이트된 키와 병합합니다.
질문에 대한 정확한 답변:
hash = {"_id"=>"4de7140772f8be03da000018"}
hash.transform_keys { |key| key[1..] }
# => {"id"=>"4de7140772f8be03da000018"}
방법transform_keys
Ruby 버전 2.5 이후 해시 클래스에 존재합니다.
https://blog.bigbinary.com/2018/01/09/ruby-2-5-adds-hash-transform_keys-method.html
만약 당신이 해시 안에 해시가 있다면, 다음과 같은 것입니다.
hash = {
"object" => {
"_id"=>"4de7140772f8be03da000018"
}
}
그리고 만약 당신이 바꾸고 싶다면,"_id"
와 비슷한 정도로"token"
사용할 수 있습니다.deep_transform_keys
.
hash.deep_transform_keys do |key|
key = "token" if key == "_id"
key
end
결과적으로
{
"object" => {
"token"=>"4de7140772f8be03da000018"
}
}
처음에 기호 키 해시를 대신 가지고 있었다고 해도, 다음과 같은 것이 있습니다.
hash = {
object: {
id: "4de7140772f8be03da000018"
}
}
이 모든 개념을 결합하여 문자열 키 해시로 변환할 수 있습니다.
hash.deep_transform_keys do |key|
key = "token" if key == :id
key.to_s
end
키만 변경하고 , Ruby 2.8+를 2할 수 .transform_keys
방법.이 예제에서 변경하려는 경우_id
id
그러면 다음을 수행할 수 있습니다.
hash.transform_keys({_id: :id})
참조: https://bugs.ruby-lang.org/issues/16274
언급URL : https://stackoverflow.com/questions/6210572/how-can-i-replace-a-hash-key-with-another-key
'programing' 카테고리의 다른 글
포크 대.깃허브에 분기 (0) | 2023.06.03 |
---|---|
Panda를 사용하여 *.xlsx long URL을 셀에 저장하는 방법 (0) | 2023.06.03 |
레일 매개 변수가 설명되었습니까? (0) | 2023.06.03 |
루비: kind_of? vs. instance_of?vs. is_a? (0) | 2023.06.03 |
명령 프롬프트에서 apk 파일을 설치하시겠습니까? (0) | 2023.06.03 |