Daan R.
Daan R.

Reputation: 35

Ruby string array to hash

In Ruby how do you convert an array to a hash? I have an array like this

people = [
  {"name":"Sam","year":"21"},
  {"name":"cole","partition":"20"},
  {"name":"bart","year":"21"}
]

I want to put this array of in a hash like below so I can check who is 21:

{
  person1 => {"name"=>"Sam","year"=>"21"},
  person2 => {"name"=>"cole","partition"=>"20"},
  person3 => {"name"=>"bart","year"=>"21"}
}

How can I convert this array of to a hash? And how do i check who is 21?

Upvotes: 1

Views: 1468

Answers (2)

tjbp
tjbp

Reputation: 3517

First of all, it happens to be spelled "people" ;)

Since the keys person1, person2, etc. need to be generated, I would loop through your original array, placing each element into a new hash with an appropriate key:

people_hash = {}

people.each_with_index do |person, index|
    next unless person[:year] == 21 # This will skip any element that doesn't have an :age of 21

    people_hash["person#{index + 1}"] = person
end

people_hash
#=> {"person1"=>{:name=>"Sam", :year=>"21"}, "person2"=>{:name=>"cole", :partition=>"20"}, "person3"=>{:name=>"bart", :year=>"21"}}

The each_with_index method will loop through each element of the array, but will also provide the current index of the element, so that we can use it for the hash keys. I've used string interpolation to create the hash keys - since you wanted to start at 1, I've added 1 to the index each time.

Upvotes: 1

Sebastián Palma
Sebastián Palma

Reputation: 33491

You can use each_with_object to iterate over "peaple", and assign to a new hash the current element using as a key the prefix person plus the index of the current element (person).

peaple
  .each_with_object({})
  .with_index(1) do |(person, hash), index|
    hash["person#{index}"] = person
  end

# {"person1"=>{:name=>"Sam", :year=>"21"},
#  "person2"=>{:name=>"cole", :partition=>"20"},
#  "person3"=>{:name=>"bart", :year=>"21"}}

Another version just out of curiosity would be to create an array of strings with the same length of "peaple", having as values the prefix "person" plus its index plus 1. Zipping that with the current value and invoking to_h on it gives the same result:

Array.new(peaple.length) { |i| "person#{i + 1}" }.zip(peaple).to_h

If the idea is getting who's 21 by using the "year" key, then you can select those elements with year 21 and mapping then their names:

peaple
  .select { |person| person[:year] == "21" }
  .map { |person| person[:name] }
# ["Sam", "bart"]

Upvotes: 4

Related Questions