Как использовать метод копания нескольких для дочерних объектов - PullRequest
0 голосов
/ 12 июня 2018

У меня есть хеш

{:result=>
  {:"1"=>
    [{:"1"=>1,
      :"2"=>"4698192612070913717",
      :"5"=>
      {:"1"=>{:"1"=>"1.0.0"},
        :"2"=>
        {:"1"=>1,
          :"2"=>"1525341956127",
          :"3"=>1000000000,
          :"4"=>0,
          :"5"=>{:"1"=>1000000000}},
        :"3"=>["17"],
        :"6"=>"4704522736971289334",
        :"8"=>["4618851880555471022"],
        :"9"=>[1]},
      :"6"=>{:"3"=>{:"2"=>false}, :"4"=>{:"1"=>false}},
      :"7"=>{:"1"=>1},
      :"8"=>"production"},
    {:"1"=>4,
      :"2"=>"4700283765268993541",
      :"6"=>{:"2"=>{:"1"=>200}, :"3"=>{:"2"=>false}, :"4"=>{:"1"=>false}},
      :"8"=>"beta"},
    {:"1"=>5,
      :"2"=>"4699074054925986704",
      :"6"=>{:"2"=>{:"1"=>100}, :"3"=>{:"2"=>false}, :"4"=>{:"1"=>false}},
      :"8"=>"alpha"},
    {:"1"=>10,
      :"2"=>"4697702456121346981",
      :"6"=>{:"2"=>{:"1"=>50}, :"3"=>{:"2"=>false}, :"4"=>{:"1"=>false}},
      :"8"=>"internal"}],
  :"3"=>{:"1"=>true, :"2"=>{:"1"=>{:"1"=>false}, :"2"=>{:"1"=>false}}},
  :"4"=>false},
:xsrf=>"AMtNNDFJl06mR54j2zxFjYIYfGQR22sUKA:1528830206790"}

Я ищу простой способ вернуть значение или ноль

Я пробовал это

result[:'result'][:'1'][1].dig(:'5').dig(:'1').dig(:'1')

, но это не такработает

Что я могу сделать, чтобы избежать этого

if result[:'result'][:'1'][1].dig(:'5')
puts result[:'result'][:'1'][1][:'5'][:'1'][:'1']
end

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

dig - не единственный метод, а семейство из четырех методов, каждый из которых дебютировал в Ruby v2.3: Array # dig , Hash # dig , Struct # dig и OpenStruct # dig .

Например,

h = { a: [1, { c: 2, d: 3 }], b: 2 }
h.dig(:a, 1, :d)
  #=> 3

использует Hash#dig, поскольку получатель dig является хэшем.Более того, можно ожидать, что когда в промежуточном расчете dig раскопал [1, { c: 2, d: 3 }], он передаст лопату в Array#dig для дальнейших раскопок.

Предположим,

h = { a: [1, 2] }

Тогда

h.dig(:a, 1)        #=> 2
h.dig(:a).dig(1)    #=> 2

Означает ли это, что два эквивалентны?Попробуйте это:

h.dig('cat', 1)     #=> nil
h.dig('cat').dig(1) #=> NoMethodError: undefined method `dig' for nil:NilClass

Исключение связано с тем, что h.dig('cat') #=> nil и NilClass не имеют метода экземпляра dig, поэтому nil.dig(1) вызывает исключение.Нет, два выражения не эквивалентны.

Если значение переменной result является хэшем OP, мы имеем (как указано @Isaiah) следующее.

result.dig(:result, :'1', 0, :"5", :"1", :"1")
  #=> "1.0.0"
result.dig(:result, :'1', 0, :cat, :"1", :"1")
  #=> nil

Обратите внимание, что dig будет вызывать исключение, если используется неправильный тип данных:

[1, 2].dig(:a)
  #=> TypeError: no implicit conversion of Symbol into Integer

Для поддержки версий Ruby до 2.3 (где dig недоступно) мы можем написать следующее, используя Enumerable # уменьшите (он же inject).

arr = [:result, :'1', 0, :"5", :"1", :"1"]
arr.reduce(result) { |memo, obj| memo && memo[obj] }
  #=> "1.0.0"

arr = [:result, :'1', 0, :cat, :"1", :"1"]
arr.reduce(result) { |memo, obj| memo && memo[obj] }
  #=> nil
0 голосов
/ 13 июня 2018

Идея, лежащая в основе dig, заключается в том, что вы можете одновременно перейти на несколько уровней в хэш и вернуть nil, если ключ не существует ни на одном уровне во время «копания».Так что result[:'result'][:'1'][1].dig(:'5', :'1', :'1') сделает то, что вы ищете, и очистите ваш код.На самом деле, вы можете сделать это немного безопаснее, если захотите, набрав result.dig(:result, :'1', 1, :'5', :'1', :'1')

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...