访问哈希和数组Ruby

时间:2012-05-05 09:25:57

标签: ruby json symbols

在我的Rails应用程序中,我发送了一个需要解码的复杂JSON字符串。这不是我知道的问题。

在我实现所有内容之前,我正在尝试访问一些示例JSON结构,以查看是否可以获取所有变量。问题是名称可以变化。

{"configurations" : [ 
{ "drinks" : [
        {"menus" : [
          { "hot" : [
            {"id":15,"unit":"0.33", "price":"1", "currency":"Euro", "position": 4},
            {"id":15,"unit":"0.33", "price":"1", "currency":"Euro", "position": 6}
          ] },

          { "cold" : [
        {"id":15,"unit":"0.33", "price":"1", "currency":"Euro", "position": 4},
            {"id":15,"unit":"0.33", "price":"1", "currency":"Euro", "position": 6}
           ] },

          { "terminals" : [ {"id" : 4}, {"id": 6}, {"id": 7} ] }, 

          { "keys" : { "debit" : "on", "credit": "off" }  }

        ] }
] } ] } 

好的,现在以下字段是可变的“drink”,“hot”,“cold”。所有其他字段将被称为相同。

现在我想在解码之后访问此JSON字符串中的每个变量。在实现之前,我尝试了一个简单的JSON:

{"configuration" : [ { "drinks" : [ { "id":15, "unit":"0.33" } ] } ] }

在rails中解码导致

{ "configuration" => [{"drinks" => [{"id" => 15, "unit" => "0.33" }]}]}

现在我如何在不使用“饮料”一词的情况下访问idunit。解决方案也应该可以扩展到上面的例子。

一些额外的信息:在大型JSON中,我应该访问那里列出的所有项目(id的)将它们保存到表中并返回新的id,然后将其插入JSON中。 (解释为什么需要这样做需要额外的页面或4 ^^)。

3 个答案:

答案 0 :(得分:3)

我写这篇文章是为了深入挖掘Hash,但是首先你的json有些问题我害怕,当你解析它时你会得到这个,你会注意到例如终端没有显示所有的键。代码仍然需要适应返回数组或散列本身。

hash = JSON.parse(string) #the string you published
=>

{"configurations"=>
  [{"drinks"=>
     [{"menus"=>
        [{"hot"=>
           [{"id"=>15,
             "unit"=>"0.33",
             "price"=>"1",
             "currency"=>"Euro",
             "position"=>4},
            {"id"=>15,
             "unit"=>"0.33",
             "price"=>"1",
             "currency"=>"Euro",
             "position"=>6}]},
         {"cold"=>
           [{"id"=>15,
             "unit"=>"0.33",
             "price"=>"1",
             "currency"=>"Euro",
             "position"=>4},
            {"id"=>15,
             "unit"=>"0.33",
             "price"=>"1",
             "currency"=>"Euro",
             "position"=>6}]},
         {"terminals"=>{"id"=>7}},
         {"keys"=>{"debit"=>"on", "credit"=>"off"}}]}]}]}

这里是代码

class Hash
  def dseek(search_key = "", path = "")
    self.each do|key, value|
      if value.is_a?(Hash)
        path += "#{key}."
        value.dseek(search_key, path)
      else
        if value.is_a?(Array)
          path += "#{key}."
          value.each do |val|
            val.dseek(search_key, path)
          end
        else
          puts "#{path}#{key}:#{value}" if search_key === key || search_key === ""
        end
      end
    end
  end
end


hash.dseek

给出

configurations.drinks.menus.hot.id:15
configurations.drinks.menus.hot.unit:0.33
configurations.drinks.menus.hot.price:1
configurations.drinks.menus.hot.currency:Euro
configurations.drinks.menus.hot.position:4
configurations.drinks.menus.hot.id:15
configurations.drinks.menus.hot.unit:0.33
configurations.drinks.menus.hot.price:1
configurations.drinks.menus.hot.currency:Euro
configurations.drinks.menus.hot.position:6
configurations.drinks.menus.cold.id:15
configurations.drinks.menus.cold.unit:0.33
configurations.drinks.menus.cold.price:1
configurations.drinks.menus.cold.currency:Euro
configurations.drinks.menus.cold.position:4
configurations.drinks.menus.cold.id:15
configurations.drinks.menus.cold.unit:0.33
configurations.drinks.menus.cold.price:1
configurations.drinks.menus.cold.currency:Euro
configurations.drinks.menus.cold.position:6
configurations.drinks.menus.terminals.id:7
configurations.drinks.menus.keys.debit:on
configurations.drinks.menus.keys.credit:off

hash.dseek("id")

给出

configurations.drinks.menus.hot.id:15
configurations.drinks.menus.hot.id:15
configurations.drinks.menus.cold.id:15
configurations.drinks.menus.cold.id:15
configurations.drinks.menus.terminals.id:7

答案 1 :(得分:1)

总而言之,有一个哈希似乎有点奇怪,但后来对密钥不感兴趣,但是我要判断谁,你可能会从其他地方或其他地方获得那些奇怪的数据。

鉴于上面的简化示例,您可以这样做:

h["configuration"].first.values.flatten.first 
#=> {"id"=>15, "unit"=>"0.33"}

现在让我们看看更复杂的例子:

h["configurations"].map(&:values).flatten.first["menus"].map(&:values).flatten.map { |x| x["id"] }.compact
#=> [15, 15, 15, 15, 7]

这会返回id,但是很难看,并且会丢失id来自的所有信息。没有看到更多的代码,我不知道这是否足够(可能不是)。

答案 2 :(得分:1)

在你的评论中,你说

  

每个终端都有一个配置(“饮料”),并且可以有多个子菜单(“热”,“冷”),所有子菜单最多有24个项目(“id”等等)

但是你发布的JSON似乎反映了一个不同的结构,这让我认为你的任务变得不必要。如果JSON宁愿按照您在评论中描述的方式按层次结构进行分组,那么您的任务将变得非常简单。听起来你有可能改变生成的JSON,所以我建议你重新设计它的层次结构,而不是试图编写难以理解/维护的代码来处理一开始并不理想的数据结构。

作为一个例子,你说一个终端意味着它的配置和菜单,所以我会把终端放在顶层而不是配置上,也就是说,使配置和菜单成为终端的一员而不是另一种方式。这样,您可以简单地遍历所有终端,访问其菜单,ID等,而无需知道此特定终端提供“饮料”。