Programing

Ruby JSON 구문 분석으로 해시 키 변경

lottogame 2020. 11. 23. 07:37
반응형

Ruby JSON 구문 분석으로 해시 키 변경


이 해시가 있다고 가정 해 봅시다.

{
  :info => [
    {
        :from => "Ryan Bates",
        :message => "sup bra",
        :time => "04:35 AM"
    }
  ]
}

을 수행하여 정보 배열을 호출 할 수 있습니다 hash[:info].

이제 이것을 JSON (JSON.generate)으로 변환 한 다음 구문 분석 (JSON.parse)하면이 해시를 얻습니다.

{
  "info" => [
    {
        "from" => "Ryan Bates",
        "message" => "sup bra",
        "time" => "04:35 AM"
    }
  ]
}

이제 사용 hash[:info]하면 반환 nil되지만 사용 하면 반환 되지 않습니다 hash["info"].

왜 이런거야? 그리고 어쨌든이 비 호환성을 수정할 수 있습니까 (처음부터 문자열 키를 사용하는 것 외에)?


요컨대, 아닙니다. 이런 식으로 생각해보세요. JSON에 기호를 저장하는 것은 JSON에 문자열을 저장하는 것과 같습니다. 따라서 JSON 문자열을 구문 분석 할 때 둘을 구분할 수 없습니다. 물론 문자열 키를 다시 기호로 변환하거나 실제로 JSON과 상호 작용하는 클래스를 빌드하여이를 자동으로 수행 할 수 있지만 문자열을 사용하는 것이 좋습니다.

그러나이를 위해 이전에 질문을 받았을 때이 질문에 대한 답변은 다음과 같습니다.

json 형식의 키 값 쌍을 기호를 키로 사용하는 루비 해시로 변환하는 가장 좋은 방법은 무엇입니까?

ActiveSupport :: JSON 디코딩 해시 손실 기호

또는 HashWithIndifferentAccess


JSON 생성기는 JSON이 기호를 지원하지 않기 때문에 기호를 문자열로 변환합니다. JSON 키는 모두 문자열이므로 JSON 문서를 구문 분석하면 기본적으로 문자열 키가있는 Ruby 해시가 생성됩니다.

symbolize_names옵션 을 사용하여 구문 분석기에 문자열 대신 기호를 사용하도록 지시 할 수 있습니다 .

예:

original_hash = {:info => [{:from => "Ryan Bates", :message => "sup bra", :time => "04:35 AM"}]}
serialized = JSON.generate(original_hash)
new_hash = JSON.parse(serialized, {:symbolize_names => true})

new_hash[:info]
 #=> [{:from=>"Ryan Bates", :message=>"sup bra", :time=>"04:35 AM"}]

참조 : http://www.ruby-doc.org/stdlib-1.9.3/libdoc/json/rdoc/JSON.html#method-i-parse


with_indifferent_access 메서드를 호출하여 비슷한 문제를 해결했습니다.

여기에 json 문자열이 있고 변수 s에 할당 할 수 있습니다.

s = "{\"foo\":{\"bar\":\"cool\"}}"

이제 JSON 클래스로 데이터를 구문 분석하고 h에 할당 할 수 있습니다.

h = JSON.parse(s).with_indifferent_access

그러면 문자열이나 기호를 키로 받아 들일 수있는 해시가 생성됩니다.

h[:foo]["bar"]
  #=> "cool"

  1. ActiveSupport :: JSON.decode를 사용하면 json 파서를 더 쉽게 바꿀 수 있습니다.
  2. ActiveSupport :: JSON.decode (my_json, symbolize_names : true) 사용

이것은 해시의 모든 키를 재귀 적으로 상징합니다.

(루비 2.0에서 확인)


해시의 모든 키를 수정하여 문자열에서 기호로 변환 할 수 있습니다.

symbol_hash = Hash[obj.map{ |k,v| [k.to_sym, v] }]

puts symbol_hash[:info]
# => {"from"=>"Ryan Bates", "message"=>"sup bra", "time"=>"04:35 AM"}

불행히도 배열 내부에 중첩 된 해시에는 작동하지 않습니다. 그러나 모든 해시 키를 변환하는 약간의 재귀 메서드를 작성할 수 있습니다.

def symbolize_keys(obj)
  #puts obj.class # Useful for debugging
  return obj.collect { |a| symbolize_keys(a) } if obj.is_a?(Array)
  return obj unless obj.is_a?(Hash)
  return Hash[obj.map{ |k,v| [k.to_sym, symbolize_keys(v)] }]
end

symbol_hash = symbolize_keys(hash)
puts symbol_hash[:info]
# => {:from=>"Ryan Bates", :message=>"sup bra", :time=>"04:35 AM"}

이 옵션은 사용할 수 없습니다.

ActiveSupport::JSON.decode(str_json, symbolize_names: true)

Rails 4.1 ActiveSupport::JSON.decode이상 에서는 더 이상 MultiJSON에 대한 옵션 해시를 허용하지 않습니다. MultiJSON의 수명이 다하여 제거되었습니다.

You can use symbolize_keys to handle it.

ActiveSupport::JSON.decode(str_json).symbolize_keys

참고URL : https://stackoverflow.com/questions/7543779/ruby-json-parse-changes-hash-keys

반응형