Home > Back-end >  iterating over nested hash ruby
iterating over nested hash ruby

Time:08-03

  people = {
    "fruits" => {
        kiwi: ["john","james","diana"],
        apple: ["hibaq","nura","nadia"],
        strawberry: ["hana", "valerie","india"]  },
    "sports" => {
        rugby: ["john","james","diana"],
        football: ["hibaq","nura","nadia"],
        tennis: ["hana", "valerie","india"]
    }
  }

puts 'Enter what category to search'
category = gets.chomp
puts 'Enter what value to search for'
value = gets.chomp

people.select { |person| person[category] == value }
.each { |person| puts person["name"] }

Hi, I am new to ruby and trying to understand hashes a bit more. I want to ask the user for a category e.g "fruits" and then print the array of names that like the fruit. I am unsure how to iterate through the nested hash to access the information. Any guidance would be greatly appreciated. Thank you

Hi, I am new to ruby and trying to understand hashes a bit more. I want to ask the user for a category e.g "fruits" and then print the array of names that like the fruit. I am unsure how to iterate through the nested hash to access the information. Any guidance would be greatly appreciated. Thank you

CodePudding user response:

The following should work for you.

Please note that I changed the nested hash structure to use Strings instead of Symbols in the inner hashes. Because gets returns already a string that makes it easier to get the data by the key (string) that the user entered.

people = {
  "fruits" => {
    "kiwi" => ["john","james","diana"],
    "apple" => ["hibaq","nura","nadia"],
    "strawberry" => ["hana", "valerie","india"]  
  },
  "sports" => {
    "rugby" => ["john","james","diana"],
    "football" => ["hibaq","nura","nadia"],
    "tennis" => ["hana", "valerie","india"]
  }
}

puts 'Enter what category to search'
category = gets.chomp                   # when entered "sports"
puts 'Enter what value to search for'
value = gets.chomp                      # when entered "rudby"

p people.dig(category, value)
#=> ["john", "james", "diana"]           

See Hash#dig. Other options to get data out of a Hash might be Hash#[] or Hash#fetch.

CodePudding user response:

Firstly, you would make life simpler for yourself by using a consistent format when writing your hash people. I suggest

people = {
  fruits: {
    kiwi: ["john","james","diana"],
    apple: ["hibaq","nura","nadia"],
    strawberry: ["hana", "valerie","india"]  },
  sports: {
    rugby: ["john","james","diana"],
    football: ["hibaq","nura","nadia"],
    tennis: ["hana", "valerie","india"]
  }
}

Notice that I have written fruits: { ... rather than 'fruits' => { ... to be consistent with, for example, kiwi: [ ....

With this change we can write the following helper method which can be used for both the outer hash and the inner hashes.

def obtain_response(keys, type) 
  loop do
    puts "Enter what #{type} to search for"
    k = gets.chomp.to_sym
    break k if keys.include?(k)
    puts "There is no such #{type} '#{k}'. Please try again"
  end  
end

We may then write

category = obtain_response(people.keys, 'category')
value =  obtain_response(people[category].keys, 'value')
p people[category][value]

Here is an example session.

category = obtain_response(people.keys, 'category')
Computer                             User
--------                             ----
Enter what category to search for
                                     colours
There is no such category 'colours'. Please try again
Enter what category to search for
                                     sports

Now

category
  #=> :sports

Next

value =  obtain_response(people[category].keys, 'value')
Computer                             User
--------                             ----
Enter what value to search for
                                     darts
There is no such value 'darts'. Please try again
Enter what value to search for
                                     football

Now

value
  #=> :football

We may now display the desired array.

p people[category][value]
  #=> ["hibaq", "nura", "nadia"]

One may of course employ more elaborate prompts, such as

Enter the category to search for ("fruits" or "sports")
  • Related