2014-11-21 135 views
1

第一次在這裏發佈。 無法進入JSON,我可以使用一些活動的。通過Ruby中嵌套的JSON迭代

,我需要的數據是在這個級別:

restaurant["menu"][0]["children"][0]["name"] 

restaurant["menu"][0]["children"][0]["id"] 

我想基於「名」的「ID」 S數組。

這是我的工作方法:

def find_burgers(rest) 

    array = [] 

    rest["menu"].each do |section| 
    section["children"].each do |innersection| 
    innersection["name"].downcase.split.include?("burger") 
    array.push(innersection["id"]) 
    end 
    end 
    return array 
end 

正如你可以想像,我又回到每一個「ID」的漢堡包數組,而不僅僅是「ID」 S。我已經嘗試了許多.map和.keep_if的組合。

感謝您的閱讀。

編輯:這是一個菜單項:

{ 
    "children" => [ 
    [ 0] { 
     "availability" => [ 
      [0] 0 
     ], 
      "children" => [ 
      [0] { 
          "children" => [ 
        [0] { 
         "availability" => [ 
          [0] 0 
         ], 
          "descrip" => "", 
            "id" => "50559491", 
         "is_orderable" => "1", 
           "name" => "Single", 
           "price" => "0.00" 
        }, 
        [1] { 
         "availability" => [ 
          [0] 0 
         ], 
          "descrip" => "", 
            "id" => "50559492", 
         "is_orderable" => "1", 
           "name" => "Double", 
           "price" => "2.25" 
        } 
       ], 
           "descrip" => "What Size Would You Like?", 
        "free_child_select" => "0", 
            "id" => "50559490", 
         "is_orderable" => "0", 
        "max_child_select" => "1", 
       "max_free_child_select" => "0", 
        "min_child_select" => "1", 
           "name" => "Milk Burger Size" 
      }, 
      [1] { 
          "children" => [ 
        [0] { 
         "availability" => [ 
          [0] 0 
         ], 
          "descrip" => "", 
            "id" => "50559494", 
         "is_orderable" => "1", 
           "name" => "Bacon", 
           "price" => "2.00" 
        } 
       ], 
           "descrip" => "Add", 
        "free_child_select" => "0", 
            "id" => "50559493", 
         "is_orderable" => "0", 
        "max_child_select" => "1", 
       "max_free_child_select" => "0", 
        "min_child_select" => "0", 
           "name" => "Burgr Ad Bacon Optn" 
      } 
     ], 
      "descrip" => "American cheese, lettuce, tomato and Milk Sauce", 
        "id" => "50559489", 
     "is_orderable" => "1", 
       "name" => "Milk Burger", 
       "price" => "4.25" 
    }, 
+0

你能也張貼JSON /解析的哈希? – August 2014-11-21 03:39:20

+0

我會在上面貼一張。 – 2014-11-21 04:22:07

回答

3

在一般情況下,你可以通過這樣的嵌套哈希迭代:

def iterate(h) 
    h.each do |k, v| 
    if v.is_a?(Hash) || v.is_a?(Array) 
     iterate(v) 
    else 
     puts("k is #{k}, value is #{v}") 
    end 
    end 
end 

不過既然你有具體的,硬編碼名稱children, name,等等,似乎只有這樣做的方式就是你這樣做。

1

您正在執行測試以查看名稱是否包含「漢堡包」,但您對測試結果沒有做任何處理。試試這個:

def find_burgers(rest) 

    array = [] 

    rest["menu"].each do |section| 
    section["children"].each do |innersection| 
     array.push(innersection["id"]) if innersection["name"].downcase.split.include?("burger") 
    end 
    end 
    return array 
end 

此外,請考慮使用正則表達式而不是`downcase.split.include?'像這樣:

def find_burgers(rest) 

    array = [] 

    rest["menu"].each do |section| 
    section["children"].each do |innersection| 
     array.push(innersection["id"]) if innersection["name"] =~ /\bburger\b/i 
    end 
    end 
    return array 
end 

正則表達式如果名稱包含字符串「漢堡」,由字符包圍(\ b)中忽略大小寫(/ I)返回true。

最後(我覺得)你可以使用像這樣一個功能更強大的方法:

def find_burgers(rest) 
    rest["menu"].map do |section| 
    section["children"].select do |innersection| 
     innersection["name"] =~ /\bburger\b/i 
    end 
    end.flatten.map {|item| item["id"] } 
end 

select只返回匹配正則表達式的這些項目,第一map傳回匹配innersections數組每個section,flatten將陣列變成一個簡單的數組,最終的地圖從每個innersection中挑選出id

我想我已經走得太遠了。

+0

這樣做!我對編寫代碼很陌生,而且在這方面花了(浪費?)時間,所以我非常感激。 – 2014-11-21 04:27:02

+0

酷!保持它 - 它變得更容易。如果這是你需要的,請考慮接受我的答案。 – 2014-11-21 05:11:15

2

一點更準確的答案是遍歷散列或數組的JSON

j = {'key$1' => 'asdada', 
    'key$2' => ['key$3' => 2, 
       'key$4' => 's', 
       'key$6' => ['key$7' => 'man', 
          'key$8' => 'super'] 
       ], 
    'key5' => 5 } 

def iterate(i) 
    if i.is_a?(Hash) 
    i.each do |k, v| 
     if v.is_a?(Hash) || v.is_a?(Array) 
     puts("k is #{k}, value is #{v}") 
     iterate(v) 
     else 
     puts("k is #{k}, value is #{v}") 
     end 
    end 
    end 
    if i.is_a?(Array) 
    i.each do |v| 
     iterate(v) 
    end 
    end 
end 

iterate(j)