如何从json获取特定的键值?

时间:2017-01-21 01:38:17

标签: json ruby

我需要获得' name'的所有价值。密钥,同时获得孩子的价值观'键。我只能检索'名称'从第一级开始,但坚持与孩子们在一起#39;因为并非所有的名字都是'拥有他们。

puts data['labels'].collect { |item| item['name'] }

JSON响应如下:

{"labels": [{
    "name": "Crime"
}, {
    "name": "Demonstrations"
}, {
    "name": "Music",
    "children": [{
        "name": "Awards"
    }, {
        "name": "Classical"
    }, {
        "name": "Country"
    }, {
        "name": "Other"
    }, {
        "name": "Pop"
    }, {
        "name": "Soul"
    }, {
        "name": "X Factor"
    }]
}, {
    "name": "Politics"
}, {
    "name": "Rescue"
}, {
    "name": "Special Events"
}, {
    "name": "Sports",
    "children": [{
        "name": "Auto Racing"
    }, {
        "name": "Awards"
    }, {
        "name": "Baseball"
    }, {
        "name": "Basketball"
    }, {
        "name": "NASCAR (Cup)"
    }, {
        "name": "NASCAR (Nationwide)"
    }, {
        "name": "NASCAR (Truck)"
    }, {
        "name": "NASCAR (XFINITY)"
    }, {
        "name": "Other"
    }, {
        "name": "Rodeo"
    }, {
        "name": "Rugby"
    }, {
        "name": "Running"
    }, {
        "name": "Sailing"
    }, {
        "name": "Skating"
    }, {
        "name": "Volleyball"
    }]
}, {
    "name": "Traffic"
}, {
    "name": "Weather"
}]}

2 个答案:

答案 0 :(得分:2)

puts data['labels'].collect { |item| item['name'] }

会抛出错误

NoMethodError: undefined method `map' for nil:NilClass

因为你的键是符号,而不是字符串。

另外

  

同时获得孩子们的价值观'键

您确定要获得钥匙吗?因为所有键都相同(:name)。可能你需要价值观吗?无论如何,如果您需要密钥,只需将values更改为以下解决方案中的keys

现在解决方案(使用安全导航器(&)):

data[:labels].map { |item| [item[:name], item[:children]&.map(&:values)] }
# => [["Crime", nil],
#     ["Demonstrations", nil],
#     ["Music", ["Awards", "Classical", "Country", "Other", "Pop", "Soul", "X Factor"]],
#     ["Politics", nil],
#     ["Rescue", nil],
#     ["Special Events", nil],
#     ["Sports", ["Auto Racing", "Awards", "Baseball", "Basketball", "NASCAR (Cup)", "NASCAR (Nationwide)", "NASCAR (Truck)", "NASCAR (XFINITY)", "Other", "Rodeo", "Rugby", "Running", "Sailing", "Skating", "Volleyball"]],
#     ["Traffic", nil],
#     ["Weather", nil]
#   ]

以上解决方案不使用安全导航器:

data[:labels].map { |item| [item[:name], item[:children] ? item[:children].map(&:values) : nil] }

答案 1 :(得分:1)

如果你的哈希是h,你可以写

h[:labels].map do |f|
  g = { name: f[:name] }
  f.key?(:children) ? g.merge(children: f[:children].flat_map(&:values)) : g
end
  #=> [{:name=>"Crime"},
  #    {:name=>"Demonstrations"},
  #    {:name=>"Music",
  #     :children=>["Awards", "Classical", "Country", "Other", "Pop", "Soul", "X Factor"]
  #    },
  #    {:name=>"Politics"},
  #    {:name=>"Rescue"},
  #    {:name=>"Special Events"},
  #    {:name=>"Sports",
  #     :children=>["Auto Racing", "Awards", "Baseball", "Basketball", "NASCAR (Cup)",
  #                 "NASCAR (Nationwide)", "NASCAR (Truck)", "NASCAR (XFINITY)", "Other",
  #                 "Rodeo", "Rugby", "Running", "Sailing", "Skating", "Volleyball"]
  #    },
  #    {:name=>"Traffic"},
  #    {:name=>"Weather"}
  #   ]

这使用方法Hash#key?Hash#mergeEnumerable#flat_map以及一些更常见的方法。