[Ruby] How to retrieve the hash value in the array with Ruby

1 minute read

I didn’t know how much I was surprised when I touched Ruby after a long time, so I looked it up.

In the case of such an unpleasant array and hash combination.

test.rb


user_data = [
  {user: {profile: {name:'George', sex:'man' }} },
  {user: {profile: {name:'Alice', sex:'woman' }} },
  {user: {profile: {name:'Taro', sex:'man' }}}
]

Inside the array, there is a hash called user, and there is a hash called profile that is nested, and the value is entered in the key called name… I don’t know why.

Let’s take this out.

Take out “George”.

Like this

test.rb


puts user_data[0][:user][:profile][:name]

If you take out’Alice’, it looks like this

test.rb


puts user_data[1][:user][:profile][:name]

I just changed the position of the array.

To retrieve the gender in the hash of’Alice’

test.rb


puts user_data[1][:user][:profile][:sex]

I just changed :name to :sex.

retrieve all :names in the array

Since it is an array, each is taken out using each.

test.rb


user_data.each do |values|
  puts values[:user][:profile][:name]
end

The result will be

test.rb


George
Alice
Taro

When using the dig method

Since Ruby 2.3, a new method called dig is available for hash classes.

Try to retrieve’Gorge’ using the dig method

test.rb


puts user_data.dig(0, :user, :profile, :name)

If the hash is included in the array, just put in the argument what data you want.

Extract all’:name’ using dig method

test.rb


user_data.each do |values|
  puts values.dig(:user, :profile, :name)
end

Advantages of using the dig method

It seems to be the difference between returning an error and nil if the key is not found. If you use dig, it will be returned as nil, so you do not need to take measures against errors. (Until then, I used to use the fetch method)

test.rb


user_data = [
  {user: {}},
  {user: {}},
  {user: {}}
]

When using #dig
user_data.each do |values|
  puts values.dig(:user, :profile, :age)
end

If you didn't use #dig
user_data.each do |values|
  puts values[:user][:profile][:age]
end

The result looks like this

test.rb


% ruby tmp/test.rb
#=> nil

#=> undefined method `[]' for nil:NilClass (NoMethodError)