'Could someone explain me what is the difference between Hash#dig vs Hash#fetch

I'm trying to obtain a nested value in a hash. I've tried using Hash#fetch and Hash#dig but I don't understand how they should be combined.

My hash is as follows.

response = {
   "results":[
      {
         "type":"product_group",
         "value":{
            "destination":"Rome"
         }
      },
      {
         "type":"product_group",
         "value":{
            "destination":"Paris"
         }
      },
      {
         "type":"product_group",
         "value":{
            "destination":"Madrid"
         }
      }
   ]
}

I've tried the following

response.dig(:results)[0].dig(:value).dig(:destination) #=> nil
response.dig(:results)[0].dig(:value).fetch('destination') #=> Rome

The desired return value is "Rome". The second expression works but I would like to know if it can be simplified.

I'm using Ruby v2.5 and Rails v5.2.1.1.



Solution 1:[1]

Hash#dig

dig(key, ...) ? object

Extracts the nested value specified by the sequence of key objects by calling dig at each step, returning nil if any intermediate step is nil.

Hash#fetch

fetch(key [, default] ) ? obj

fetch(key) {| key | block } ? obj

Returns a value from the hash for the given key. If the key can't be found, there are several options: With no other arguments, it will raise a KeyError exception; if default is given, then that will be returned; if the optional code block is specified, then that will be run and its result returned.

That how difference looks at your example:

response = {
  "results": [
    {
      "type": 'product_group',
      "value": {
        "destination": 'Rome'
      }
    },
    {
      "type": 'product_group',
      "value": {
        "destination": 'Paris'
      }
    },
    {
      "type": 'product_group',
      "value": {
        "destination": 'Madrid'
      }
    }
  ]
}

response[:results].first.dig(:value, :destination) #=> "Rome"
response[:results].first.fetch(:value).fetch(:destination) #=> "Rome"

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community