14

Sorry if this obvious, I'm just not getting it. If I have an array of hashes like:

people = [{:name => "Bob", :occupation=> "Builder"}, {:name => "Jim", :occupation =>
"Coder"}]

And I want to iterate over the array and output strings like: "Bob: Builder". How would I do it? I understand how to iterate, but I'm still a little lost. Right now, I have:

people.each do |person|
  person.each do |k,v|
    puts "#{v}"
  end
end

My problem is that I don't understand how to return both values, only each value separately. What am I missing?

Thank you for your help.

Promise Preston
  • 24,334
  • 12
  • 145
  • 143
splatoperator
  • 227
  • 1
  • 2
  • 10

3 Answers3

22

Here you go:

puts people.collect { |p| "#{p[:name]}: #{p[:occupation]}" }

Or:

people.each do |person|
  puts "#{person[:name]}: #{person[:occupation]}"
end

In answer to the more general query about accessing the values in elements within the array, you need to know that people is an array of hashes. Hashes have a keys method and values method which return the keys and values respectively. With this in mind, a more general solution might look something like:

people.each do |person|
  puts person.values.join(': ')
end
Richard Cook
  • 32,523
  • 5
  • 46
  • 71
2

Will work too:

people.each do |person|
  person.each do |key,value|
    print key == :name ? "#{value} : " : "#{value}\n"
  end
end

Output:

Bob : Builder
Jim : Coder
Varus Septimus
  • 1,510
  • 20
  • 13
0

Will work too:

people.each do |name:, occupation:|
  occupation ||= 'unemployed'
  puts "#{name} : #{occupation}"
end

Ruby 3+ (thanks to Leo)

people.each do |person|
  person => {name:, occupation:}
  occupation ||= 'unemployed'
  puts "#{name} : #{occupation}"
 end
 
  • 1
    I like this pattern, just wanted to point out it doesn't work in Ruby 3+ - one option is to use rightward assignment, e.g. `people.each { |person| person => { name:, occupation: }; puts "#{name} : #{occupation}" } – Leo Aug 30 '23 at 10:44