2016-05-30 136 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.parse(fruit_production)轉換成JSON對象,但我怎麼能真正從中得到的數據並在此之後循環?例如:

  1. 返回該國最高的全年水果產量
  2. 返回歐洲國家最高溫暖的季節(春,夏)果實產量
  3. 返回來自全國映射佔全年總產量,即{荷蘭:1818,泰國:8200等}
  4. 返回每個區域的全球總產量的映射,例如{north:28333,south:91339,east:14343,west:50290}

回答

1

you ca ñ轉換與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字符串檢索信息,以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]