Ruby Hash and Array Access

In my Rails application, I am sending a complex JSON string that needs to be decrypted. This is not a problem that I know how.

Now, before I implement everything that I try to get in some examples of the JSON structure, to see if I can get all the variables. The problem is that names can be variables.

{"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" }  }

        ] }
] } ] } 

So, now the following fields are variables : “drinks”, “hot”, “cold” . All other fields will be called the same.

Now, I would like to access every variable in this JSON string after I decrypted it. Before implementing it, I tried simple JSON:

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

After decoding in rails, resulting in

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

, , , id unit, "". .

: JSON (id), , JSON. (, , 4 ^^).

+2
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
+3

, , , , - -.

, , :

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]

, , . , , (, , ).

+1

( "" ) ( "", "" ), 24 ( "id" ..)

JSON, , , , , . JSON , , . , JSON, , / , , ,

As an example, you say that the terminal implies its configuration and menu, so I would put the terminals at the top level instead of the configurations, that is, make the configuration and menu a member of the terminal, and not vice versa. Thus, you can simply iterate through all the terminals, get access to their menus, identifiers, etc., Not knowing that this particular terminal serves, for example, as “drinks”.

+1
source

Source: https://habr.com/ru/post/1727000/


All Articles