Выполнить итерацию по json-ответу и вернуть один массив

#json #ruby

#json #ruby

Вопрос:

Приведенный ниже код возвращает мне все округа в виде строки, я могу видеть это, используя метод проверки.

 def self.all_counties
    response['ChargeDevice'].each do |charger|
        puts ['ChargeDeviceLocation']['Address']['County'].inspect
    end
end
  

Как правильно хранить каждую возвращенную строку в одном массиве, чтобы я мог манипулировать ею позже?

JSON

 "ChargeDeviceLocation"   =>   {  
  "Latitude"      =>"51.605591",
  "Longitude"      =>"-0.339510",
  "Address"      =>      { 
     "County"         =>"Greater London",
     "Country"         =>"gb"
  }
  

Комментарии:

1. Используйте map вместо each и сохраните результат в переменной.

2. Вы также можете счесть полезным использовать Hash#dig вместо повторных [] вызовов, чтобы избежать nil ошибок.

3. т.е. charger.dig('ChargeDeviceLocation', 'Address', 'County')

4. Я предполагаю, что ваш пример вызывает TypeError: no implicit conversion of String into Integer исключение, потому Address что в массиве нет индекса ['ChargeDeviceLocation'] .

5. О, и, очевидно… возвращает мне все округа в виде строки какую строку ? Если API возвращает данные в виде строки, то вы, вероятно, можете преобразовать их в массив — но я не могу сказать вам, как, не зная, какова исходная строка!

Ответ №1:

Это работает, если в ответе есть все ключи для каждого элемента:

 counties = response['ChargeDevice'].map do |r|
  r.dig('ChargeDeviceLocation', 'Address', 'County')
end
  

Что-то вроде этого даст вам nils, когда в дереве нет записей для всех элементов:

 counties = response['ChargeDevice'].map do |r|
  r.fetch('ChargeDeviceLocation', {}).
    fetch('Address', {}).
    fetch('County', nil)
end
  

Вы также можете использовать JSONPathruby JSONPath gem).

 require 'jsonpath'
counties = JsonPath.new('$..County').on(response.to_json)