Diggin through hashes and arrays in Ruby
Tags: ruby, tricks
Published: 2020-03-19 10:40:24

---
title: Diggin through hashes and arrays in Ruby
published: true
date: 2020-03-18 18:13:13 UTC
tags: ruby,tricks
canonical_url: https://prathamesh.tech/2020/03/18/diggin-through-hashes-and-arrays-in-ruby/
---

 ![Diggin through hashes and arrays in Ruby](https://prathamesh.tech/content/images/2020/03/dane-deaner-wnkE42AFNZg-unsplash.jpg)

While working with third party APIs, lot of times we get nested JSON structure in the response. Here is sample response from GitHub API.

<!--kg-card-begin: code-->
```rb
[
  {
    "id": 1,
    "title": "Found a bug",
    "body": "I'm having a problem with this.",
    "user": {
      "login": "octocat",
      "id": 1,
    },
    "labels": [
      {
        "name": "bug"   
      }
    ],
    "assignee": {
      "login": "octocat",
    },
    "assignees": [
      {
        "login": "octocat"       
      }
    ],
    "milestone": {      
      "creator": {
        "login": "octocat"
      },
      "open_issues": 4,      
    },
    "pull_request": {
      "url": "https://api.github.com/repos/octocat/Hello-World/pulls/1347"
    },
    "closed_at": null,
    "created_at": "2011-04-22T13:33:48Z",
    "updated_at": "2011-04-22T13:33:48Z"
  }
]
```
<!--kg-card-end: code-->

Once we parse this with `JSON.parse` we get a nested hash object. To reach the `creator` of the `milestone` of an

`issue`, we need to reach it as follows.

<!--kg-card-begin: code-->
```rb
issues = JSON.parse(issues_params)
issue.each do |issue|
  creator = issue[:milestone][:creator][:login]
end
```
<!--kg-card-end: code-->

Do you spot any problem with this piece of code? If the `issue[:milestone]` is `nil` then this code will fail.

We can solve this by checking if `issues[:milestone]` is not `nil` then try to access the creator. But what if

`issue[:milestone][:creator]` is `nil`?

<!--kg-card-begin: code-->
```rb
issues = JSON.parse(issues_params)
issue.each do |issue|
  creator = issue[:milestone] && issue[:milestone][:creator] && issue[:milestone][:creator][:login]
end
```
<!--kg-card-end: code-->

Instead we can use my most favorite method from Ruby which is **dig**.

> This method is available from Ruby 2.3 onwards.

#### Digging through nested hashes

Ruby provides a method `Hash#dig` which can be used in this case. As the name suggests, the method digs through the nested hash looking for keys we asked it to look for. If it finds out any key which is not present, it just returns `nil`. Let's write above code using the `Hash#dig` method.

<!--kg-card-begin: code-->
```rb

issue.each do |issue|
  creator = issue.dig(:milestone, :creator, :login)
end
```
<!--kg-card-end: code-->

If `issue[:milestone]` or `issue[:milestone][:creator]` is nil then this method will simply return `nil` instead of resulting into an error.

#### Digging arrays

Array class in Ruby also provides `dig` method.

<!--kg-card-begin: code-->
```rb
h = { colors: ["red", "blue", "yellow", "green"] }
irb(main):013:0> h.dig(:colors, 0)
=> "red"
irb(main):014:0> h.dig(:colors, 2)
=> "yellow"

```

Liked this article about handling nested hashes and arrays in Ruby? You will like my other articles about Ruby and Rails as well. Don't miss any of my blogs by subscribing to [my newsletter](https://prathamesh.tech/mailing-list)!