json 형식의 키 값 쌍을 기호가 키로 있는 루비 해시로 변환하는 가장 좋은 방법은 무엇입니까?
json 형식의 키 값 쌍을 기호를 키로 하는 루비 해시로 변환하는 가장 좋은 방법이 무엇인지 궁금합니다. 예:
{ 'user': { 'name': 'foo', 'age': 40, 'location': { 'city' : 'bar', 'state': 'ca' } } }
==>
{ :user=>{ :name => 'foo', :age =>'40', :location=>{ :city => 'bar', :state=>'ca' } } }
이것을 할 수 있는 도우미 방법이 있나요?
json 문자열을 해석할 때 json gem을 사용하여 symbol_names 옵션을 전달할 수 있습니다.여기를 참조해 주세요.http://flori.github.com/json/doc/index.html (해석 아래 참조)
예:
>> s ="{\"akey\":\"one\",\"bkey\":\"two\"}"
>> JSON.parse(s,:symbolize_names => true)
=> {:akey=>"one", :bkey=>"two"}
리벤틱스, 답변 감사합니다.
Marshal.load(Marshal.dump(h)) 메서드는 원래 키 유형을 재귀적으로 보존하기 때문에 다양한 메서드 중 가장 무결성이 높을 수 있습니다.
이는 문자열과 심볼 키가 혼재된 중첩된 해시가 있고 디코딩 시 해당 혼합을 보존하려는 경우 중요합니다(예를 들어 프로젝트 시간 등 어떠한 이유로 키를 조작/변환할 수 없는 매우 복잡하고 내구성 있는 서드파티 개체와 더불어 해시에 자체 커스텀 개체가 포함되어 있는 경우 발생할 수 있습니다).제약).
예:
h = {
:youtube => {
:search => 'daffy', # nested symbol key
'history' => ['goofy', 'mickey'] # nested string key
}
}
방법 1: JSON.parse - 모든 키를 재귀적으로 기호화 => 원래 혼합을 유지하지 않음
JSON.parse( h.to_json, {:symbolize_names => true} )
=> { :youtube => { :search=> "daffy", :history => ["goofy", "mickey"] } }
방법 2: ActiveSupport:JSON.decode - 최상위 키만 나타냅니다. = > 원래 혼합은 유지되지 않습니다.
ActiveSupport::JSON.decode( ActiveSupport::JSON.encode(h) ).symbolize_keys
=> { :youtube => { "search" => "daffy", "history" => ["goofy", "mickey"] } }
방법 3: Marshal.load - 네스트된 키에 원래 문자열/심볼 혼합을 유지합니다.완벽해!
Marshal.load( Marshal.dump(h) )
=> { :youtube => { :search => "daffy", "history" => ["goofy", "mickey"] } }
제가 모르는 단점이 없다면, 저는 방법 3이 최선이라고 생각합니다.
건배.
트릭을 하기 위해 내장된 것은 없지만 JSON 젬을 사용하여 코드를 작성하는 것은 그리 어렵지 않습니다.이 있습니다.symbolize_keys
Rails에 내장된 메서드는 필요한 키를 재귀적으로 나타내지 않습니다.
require 'json'
def json_to_sym_hash(json)
json.gsub!('\'', '"')
parsed = JSON.parse(json)
symbolize_keys(parsed)
end
def symbolize_keys(hash)
hash.inject({}){|new_hash, key_value|
key, value = key_value
value = symbolize_keys(value) if value.is_a?(Hash)
new_hash[key.to_sym] = value
new_hash
}
end
Leventix가 말했듯이 JSON gem은 이중 따옴표로 묶인 문자열만 처리합니다(기술적으로는 정확합니다.JSON은 이중 따옴표로 포맷해야 합니다).이 코드 조각은 구문 분석을 시도하기 전에 해당 코드를 정리할 것입니다.
재귀적 방법:
require 'json'
def JSON.parse(source, opts = {})
r = JSON.parser.new(source, opts).parse
r = keys_to_symbol(r) if opts[:symbolize_names]
return r
end
def keys_to_symbol(h)
new_hash = {}
h.each do |k,v|
if v.class == String || v.class == Fixnum || v.class == Float
new_hash[k.to_sym] = v
elsif v.class == Hash
new_hash[k.to_sym] = keys_to_symbol(v)
elsif v.class == Array
new_hash[k.to_sym] = keys_to_symbol_array(v)
else
raise ArgumentError, "Type not supported: #{v.class}"
end
end
return new_hash
end
def keys_to_symbol_array(array)
new_array = []
array.each do |i|
if i.class == Hash
new_array << keys_to_symbol(i)
elsif i.class == Array
new_array << keys_to_symbol_array(i)
else
new_array << i
end
end
return new_array
end
물론 json gem도 있습니다만, 이중 따옴표만 취급하고 있습니다.
이 문제를 해결하는 또 다른 방법은 YAML 시리얼화/디시리얼화를 사용하는 것입니다.이것에 의해서, 키의 형식도 유지됩니다.
YAML.load({test: {'test' => { ':test' => 5}}}.to_yaml)
=> {:test=>{"test"=>{":test"=>5}}}
이 접근방식의 장점은 REST 서비스에 더 적합한 형식인 것 같습니다.
가장 편리한 방법은 nice_filename gem을 사용하는 것입니다.https://github.com/MarioRuiz/nice_hash
require 'nice_hash'
my_str = "{ 'user': { 'name': 'foo', 'age': 40, 'location': { 'city' : 'bar', 'state': 'ca' } } }"
# on my_hash will have the json as a hash
my_hash = my_str.json
# or you can filter and get what you want
vals = my_str.json(:age, :city)
# even you can access the keys like this:
puts my_hash._user._location._city
puts my_hash.user.location.city
puts my_hash[:user][:location][:city]
문자열 키와 기호 키가 모두 필요하다고 생각되는 경우:
JSON.parse(json_string).with_indifferent_access
언급URL : https://stackoverflow.com/questions/1732001/what-is-the-best-way-to-convert-a-json-formatted-key-value-pair-to-ruby-hash-wit
'itsource' 카테고리의 다른 글
Oracle PL/SQL - 커스텀 SQLERM을 사용하여 사용자 정의 예외 발생 (0) | 2023.02.10 |
---|---|
데이터 테이블에 빈 데이터 메시지를 표시하는 방법 (0) | 2023.02.10 |
Google App Engine 모델의 JSON 직렬화 (0) | 2023.02.10 |
다른 ID로 여러 행을 동시에 업데이트 (0) | 2023.02.06 |
Python 함수가 예외를 발생시키는 것을 어떻게 테스트합니까? (0) | 2023.02.06 |