2016-05-30 3 views
1

У меня есть объект:Извлечение данных из объекта JSON в Рубине

EURO_COUNTRIES = ['France', 'Germany', 'Spain'] 
fruit_production = { 
    cuba: { 
    #meaning: country c produces k kilograms of fruit in region r for season s 
    winter: [{north: 1}, {south: nil}, {east: 4}, {west: 4}], 
    summer: [{north: nil}, {south: 5}, {east: ""}, {west: 5}], 
    }, 
    spain: { 
    fall: [{north: 7}, {}], 
    summer: [{north: nil}, {south: "5"}, {east: 2}, {west: '5'}], 
    spring: [] 
    } 
#and the list goes on for hundreds of countries 
}fruit_production = { 
    cuba: { 
    #meaning: country c produces k kilograms of fruit in region r for season s 
    winter: [{north: 1}, {south: nil}, {east: 4}, {west: 4}], 
    summer: [{north: nil}, {south: 5}, {east: ""}, {west: 5}], 
    }, 
    spain: { 
    fall: [{north: 7}, {}], 
    summer: [{north: nil}, {south: "5"}, {east: 2}, {west: '5'}], 
    spring: [] 
    } 
#and the list goes on for hundreds of countries 
} 

Я попытался преобразовать его в объект JSON с JSON.parse (fruit_production), но как я могу на самом деле получить данные из него и зацикливать его после этого? Например:

  1. Возвращение страна с самым высоким круглый год урожая плодов
  2. возвращенной европейская страна с самой высокой теплое время года (весна, лето) фруктового урожая
  3. возвращенной отображение из страны в общей сложности в год доходность, т. е. {нидерланды: 1818, таиланд: 8200 и т. д.}
  4. Возвращение картографирования общей доходности по всему миру, например {север: 28333, юг: 91339, восток: 14343, запад: 50290}

ответ

1

you ca п преобразовать JSON с to_json

> fruit_production.to_json 
=> "{\"cuba\":{\"winter\":[{\"north\":1},{\"south\":null},{\"east\":4},{\"west\":4}],\"summer\":[{\"north\":null},{\"south\":5},{\"east\":\"\"},{\"west\":5}]},\"spain\":{\"fall\":[{\"north\":7},{}],\"summer\":[{\"north\":null},{\"south\":\"5\"},{\"east\":2},{\"west\":\"5\"}],\"spring\":[]}}" 

Как для извлечения информации из строки JSON, я думаю, что вам лучше просто преобразовать его обратно в хэш и работать с этим.

1, 3) Вы можете получить годовую доходность для каждой страны путем суммирования по сезону и региону и принятия максимального значения.

примечание: ваш хэш доходности по региону излишне сложный - у вас есть массив одноэлементных хэшей вместо одного хэша, проиндексированного по региону.

ток: [{:north=>nil}, {:south=>"5"}, {:east=>2}, {:west=>"5"}]

лучше: {:north=>nil, :south=>"5", :east=>2, :west=>"5"}

Однако, это будет работать с тем, что у вас есть, хотя я уверен, что это может быть упрощено, (особенно, если принять мою рекомендацию по региону -производство структура - вы можете избавиться от порой путая inject функции и просто просуммировать по значениям хэша):

by_country = Hash[fruit_production.map { |country, production| [country, production.map {|season, data| data.inject(0) { |sum, v| sum + v.values.map(&:to_i).sum } }.sum]}] 

=> {:cuba=>19, :spain=>19} 

ой, у вас есть связь! Я не знаю, что вы хотите делать с этим делом, но вы можете просто выбрать один максимум довольно легко:

by_country.max_by { |k,v| v } 
=> [:cuba, 19] 

2) Вы можете получить подмножество fruit_production для европейских стран, выбрав элементы fruit_production которых ключ (после некоторых манипуляций строка) соответствует одному из названий стран в списке:

euro_fruit_production = fruit_production.select {|k,v| EURO_COUNTRIES.include?(k.to_s.titleize)} 

=> {:spain=>{:fall=>[{:north=>7}, {}], :summer=>[{:north=>nil}, {:south=>"5"}, {:east=>2}, {:west=>"5"}], :spring=>[]}} 

вы можете использовать, чтобы работать сезонные итоги. Удачи с остальными!

1

Чтобы начать работу, уже поздно, и я уверен, что что-то пропустил. Есть много способов обойти это.

data = fruit_production.each_with_object(Hash.new {|k,v| k[v] = Hash.new(0)}) do |(country, seasons), memo| 
    seasons.each do |season, regions| 
    regions.each do |region| 
     fruit_yield = Integer(region.values.first) rescue 0 
     memo[:total_highest_profit][country] += fruit_yield 
     memo[:total_region_yield][region.keys.first] += fruit_yield if region.keys.first 
     memo[:total_warm_season][country] += fruit_yield if season == :summer || season == :spring 
    end 
    end 
end 
# => { 
#  :total_region_yield=>{:north=>8, :south=>10, :east=>6, :west=>14}, 
#  :total_highest_profit=>{:cuba=>19, :spain=>19}, 
#  :total_warm_season=>{:cuba=>10, :spain=>12} 
# } 

Вы можете получить то, что вы хотите от этих данных, такие как высшей страны или европейской страны (для этого вам придется использовать array#include?).

data[:total_highest_profit].max_by {|_, v| v} 
# => [:cuba, 19] 
Смежные вопросы