8

Is there a way to pull the values from an array and assign them each a unique key in Ruby?

I want to be able to turn this array:

["12", "21", "1985"]

Into this hash:

{:month => "12", :day => "21", :year => "1985"}

I would rather not assign each value individually, like this:

arr = ["12", "21", "1985"]
bday_hash = {:month => arr[0], :day => arr[1], :year => arr[2]}
1
  • ary = ["12", "21", "1985"]; h = { month: ary[0], day: ary[1], year: ary[2] } Commented May 26, 2017 at 15:52

4 Answers 4

15

You can use #zip

your_array = ["12", "21", "1985"]
keys = ['month', 'day', 'year']
keys.zip(your_array).to_h
Sign up to request clarification or add additional context in comments.

1 Comment

If using ruby version < 2.1, to_h is not supported. Use Hash[keys.zip(values)] as suggested by @MikDiet below.
8

You can take array of keys, zip it with values and then convert to hash

keys = [:month, :day, :year]
values = ["12", "21", "1985"]
Hash[keys.zip(values)]
# => {:month=>"12", :day=>"21", :year=>"1985"} 

1 Comment

Yep, you were right. Documentation says "object convertible to hash". Conversion is done via .to_hash, which on hashes just returns self. And I misread the code at first and thought the conversion is done via "key value pairs" route, which would involve one intermediate hash and one array. Still it's better to use literals in cases like that one. :)
2

Here are two other ways to obtain the desired hash.

arr_values = ["12", "21", "1985"]
arr_keys   = [:month, :day, :year]

[arr_keys, arr_values].transpose.to_h
  #=> {:month=>"12", :day=>"21", :year=>"1985"}

arr_keys.each_index.with_object({}) { |i, h| h[arr_keys[i]] = arr_values[i] } 
  #=> {:month=>"12", :day=>"21", :year=>"1985"}

Comments

1

I added a method to Array to facilitate this sort of conversion.

class Array

  def fold_into_hash(values)
    result = {}

    self.each_with_index do |key, index|
      result[key] = values[index]
    end

    result
  end

end

month_day_year = [:month, :day, :year]

#...

puts month_day_year.fold_into_hash(["12", "21", "1985"])

yields this result:

{:month=>"12", :day=>"21", :year=>"1985"}

2 Comments

While you can do it this way, there's no reason to since zip and to_h or Hash[] will do it faster.
Yes, of course and answers with zip were posted. The goal is to present alternate ideas. All answers involve some level of design compromise.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.