2015-08-18 62 views
2

我有以下的JSON,紅寶石陣建設

{ 
    "items": [ 
     { 
      "name": "table", 
      "item_group": [ 
       { 
        "code": "code1", 
        "section": [ 
         {       
          "unit": "centimeter", 
          "values": [ 
           { 
            "display": "151.13 centimeter" 
           } 
          ] 
         }, 
         {       
          "unit": "centimeter (qualifier value)", 
          "values": [ 
           { 
            "display": "170.39 centimeter" 
           } 
          ] 
         } 
        ], 
        "total": 2 
       } 
      ], 
      "more_results": false, 
      "total": 1 
     } 
    ] 
} 

我如何通過這個循環,創造「價值」的數組。我想要的東西像[151.13釐米,170.39釐米,....]。請在這裏顯示一些方向。謝謝。

注:我必須在Haml做這個。

+2

你可以這樣做:'json.scan(/ \ 「顯示\」:\「(\ d + \ \ d +)釐米/)。flatten.map (&:to_f)#=> [151.13,170.39]'。 –

+1

您是否知道結構(即嵌套鍵等)還是隻想通過嵌套散列和數組挖掘,直到找到一個看起來像你想要什麼? –

+0

我建議你用單引號括起你的JSON字符串,以便它是1 –

回答

1

假設你知道基本散列的結構,你可以這樣做:

代碼

require 'json' 

JSON.parse(json_str)['items'].each_with_object([]) do |g,arr| 
    g['item_group'].each do |gg| 
    gg['section'].each do |ggg| 
     ggg['values'].each { |gggg|arr << gggg['display'][/\d+\.\d+/].to_f } 
    end 
    end 
end  
    #=> [151.13, 170.39] 

說明

的步驟如下:

a = JSON.parse(json_str) 
b = a['items'] 
enum = b.each_with_object([]) 
    #=> #<Enumerator: [{"name"=>"table",..."total"=>1}]:each_with_object([])> 

我們可以通過將其轉換爲一個數組看到枚舉的元素:

enum.to_a 
    #=> [[{"name"=>"table", "item_group"=>[{"code"=>"code1", 
    #  "section"=>[{"unit"=>"centimeter", 
    #  "values"=>[{"display"=>"151.13 centimeter"}]}, 
    #  { "unit"=>"centimeter (qualifier value)", 
    #  "values"=>[{"display"=>"170.39 centimeter"}]}], "total"=>2}], 
    #  "more_results"=>false, 
    #  "total"=>1}, 
    # []]] 

注意這個陣列具有單獨的元件,含有一個散列和空數組的兩元件陣列。

enum第一個元素被傳遞到塊和分配給使用平行分配的塊的變量:

g, arr = enum.next 
    #=> {"name"=>"table", 
    # "item_group"=>[ 
    #  {"code"=>"code1", 
    #  "section"=>[ 
    #  {"unit"=>"centimeter", 
    #   "values"=>[ 
    #   {"display"=>"151.13 centimeter"} 
    #   ] 
    #  }, 
    #  {"unit"=>"centimeter (qualifier value)", 
    #  "values"=>[ 
    #  {"display"=>"170.39 centimeter"} 
    #  ] 
    #  } 
    #  ], 
    # "total"=>2}], 
    # "more_results"=>false, 
    # "total"=>1} 
arr #=> [] 

c = g['item_group'] 
    #=> [{"code"=>"code1", 
    #  "section"=>[ 
    #  {"unit"=>"centimeter", 
    #  "values"=>[ 
    #   {"display"=>"151.13 centimeter"} 
    #   ] 
    #  }, 
    #  {"unit"=>"centimeter (qualifier value)", 
    #  "values"=>[ 
    #   {"display"=>"170.39 centimeter"} 
    #  ] 
    #  } 
    # ], 
    # "total"=>2}] 

c注的形式[hash]

c的第一個(只)元件傳遞給它的塊和分配給它的塊變量:

gg = c.first 
d = gg['section'] 
    #=> [{"unit"=>"centimeter", 
     "values"=>[ 
     {"display"=>"151.13 centimeter"} 
     ] 
     }, 
     {"unit"=>"centimeter (qualifier value)", 
     "values"=>[ 
      {"display"=>"170.39 centimeter"} 
     ] 
     } 
     ] 

ggg = d.first 
    #=> {"unit"=>"centimeter", 
    # "values"=>[ 
    #  {"display"=>"151.13 centimeter"} 
    # ] 
    # } 

e = ggg['values'] 
    #=> [{"display"=>"151.13 centimeter"}] 

gggg = e.first 
    #=> {"display"=>"151.13 centimeter"} 

f = gggg['display'] 
    #=> "151.13 centimeter" 
g = f[/\d+\.\d+/] 
    #=> "151.13" 
i = g.to_f 
    #=> 151.13 
arr << i 
    #=> [151.13] 
arr 
    #=> [151.13] 

剩餘計算是相似的。

替代表達

如果,如在實施例中,陣列JSON.parse(json_str)['items']g['item_group']ggg['values']各自含有單個元件(散列),則可以改爲寫:

JSON.parse(json_str)['items'].first['item_group'].first['section']. 
    each_with_object([]) do |g, arr| 
    arr << g['values'].first['display'][/\d+\.\d+/].to_f 
    end 
    #=> [151.13, 170.39] 

儘管我懷疑這會更有效率。

+0

是的,我已經在對象中有「item_group」了。所以我想遍歷它並在數組中添加所有的「值」。 – sp1117

+0

而不是三個循環,我們可以說g ['item_group'] ['section'] ['values']? – sp1117

+0

而問題是我在Haml中使用這個 – sp1117

1

我知道有多種方法可以做到這一點。但是如果你真的有很多複雜的JSON查詢,你可以試試ruby-jq gem。這是非常快,因爲它使用Linux管道

require 'jq' 
require 'jq/extend' 
json_content =   { 
     "items": [ 
      { 
       "name": "table", 
       "item_group": [ 
       { 
         "code": "code1", 
         "section": [ 
          {       
           "unit": "centimeter", 
           "values": [ 
            { 
             "display": "151.13 centimeter" 
            } 
           ] 
          }, 
          {       
           "unit": "centimeter (qualifier value)", 
           "values": [ 
            { 
             "display": "170.39 centimeter" 
            } 
           ] 
          } 
         ], 
         "total": 2 
        } 
       ], 
       "more_results": false, 
       "total": 1 
      } 
     ] 
    } 


jq_filter = ' .items | .[].item_group |.[].section| . [ ] .values | . [ ] .display' 

final_array = json_content.jq(jq_filter) 

    # => final_array = ["151.13 centimeter", "170.39 centimeter"] 
+0

這很有趣,@Amit。請注意,您可以編寫'json_content.jq(jq_filter).map(&:to_f)#=> [151.13,170.39]',因爲'「151.13我的狗有跳蚤」.to_f#=> 151.13'。 –