簡體   English   中英

遍歷Ruby中的嵌套JSON

[英]Iterating through nested JSON in Ruby

第一次在這里發布。 進入JSON時遇到問題,我可以使用一些主動方法。

我需要的數據在以下級別:

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

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

我想要一個基於“名稱”的“ id”數組。

這是我正在使用的方法:

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”。 我嘗試了.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"
    },

通常,您可以像下面這樣遍歷嵌套的哈希:

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等,看來唯一的方法就是您執行此操作。

在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)

您正在執行一項測試,以查看名稱中是否包含“ burger”,但您並未對測試結果做任何事情。 嘗試以下方法:

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

如果名稱包含字符串“ burger”,且字符串以斷字(\\ 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為每個section傳回一個匹配的內部section的數組,flatten將數組的數組變成一個簡單的數組,最后一個映射僅從每個內部部分中提取id

我想我走得太遠了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM