Converting an Array of Keys and an Array of Values into a Hash in Ruby

Converting an array of keys and an array of values into a hash in Ruby

The following works in 1.8.7:

keys = ["a", "b", "c"]
values = [1, 2, 3]
zipped = keys.zip(values)
=> [["a", 1], ["b", 2], ["c", 3]]
Hash[zipped]
=> {"a"=>1, "b"=>2, "c"=>3}

This appears not to work in older versions of Ruby (1.8.6). The following should be backwards compatible:

Hash[*keys.zip(values).flatten]

Ruby convert an Array to Hash values with specific keys

You can use #zip

your_array = ["12", "21", "1985"]
keys = ['month', 'day', 'year']
keys.zip(your_array).to_h

Converting array to hash (Ruby)

I'm a beginner too, so this may be a little inefficient, but this is how I would explain it (there are simpler methods I'm sure, but since you mentioned this is for a class, I thought I'd explain in long form):

hash={}

some_array.each do |item|
hash[item[0]] = item[1]
end

Just to explain that a bit, I start by creating an empty hash that I will use later.

Then I cycle through some_array using the each method. This assigns each element in some_array to the variable item. Given that some_array is a nested array (which basically means that it is an array of arrays), the item variable will take the value of the inner arrays - for example, item = [:a, 123].

Then we can access each element within item when creating the hash. Following the same example I gave earlier item[0] == :a and item[1] == 123.

Then I use some shorthand when creating hashes - i.e. hash[key] = value. In this case, I want the key to be :a (which is item[0]) and the value to be 123 (which is item[1]). So I can use hash[item[0]] = item[1].

Hope that helped!

Convert array of hashes to array

a=[{:code=>"404"}, {:code=>"302"}, {:code=>"200"}] 
puts a.map{|x|x.values}.flatten.inspect

output

["404", "302", "200"]

Converting array of stringified key value pairs to hash in Ruby

All you need to do is split each part of the array into a key and value (yielding an array of two-element arrays) and then pass the result to the handy Hash[] method:

arr = [ "Name = abc", "Id = 123", "Interest = Rock Climbing" ]

keys_values = arr.map {|item| item.split /\s*=\s*/ }
# => [ [ "Name", "abc" ],
# [ "Id", "123" ],
# [ "Interest", "Rock Climbing" ] ]

hsh = Hash[keys_values]
# => { "Name" => "abc",
# "Id" => "123",
# "Interest" => "Rock Climbing" }

Convert array of hashes to single hash with values as keys

This should do what you want

countries.each_with_object({}) { |country, h| h[country[:country].to_sym] = country[:cost] }
=> {:england=>12.34, :scotland=>56.78}

What is the best way to convert an array to a hash in Ruby

NOTE: For a concise and efficient solution, please see Marc-André Lafortune's answer below.

This answer was originally offered as an alternative to approaches using flatten, which were the most highly upvoted at the time of writing. I should have clarified that I didn't intend to present this example as a best practice or an efficient approach. Original answer follows.


Warning! Solutions using flatten will not preserve Array keys or values!

Building on @John Topley's popular answer, let's try:

a3 = [ ['apple', 1], ['banana', 2], [['orange','seedless'], 3] ]
h3 = Hash[*a3.flatten]

This throws an error:

ArgumentError: odd number of arguments for Hash
from (irb):10:in `[]'
from (irb):10

The constructor was expecting an Array of even length (e.g. ['k1','v1,'k2','v2']). What's worse is that a different Array which flattened to an even length would just silently give us a Hash with incorrect values.

If you want to use Array keys or values, you can use map:

h3 = Hash[a3.map {|key, value| [key, value]}]
puts "h3: #{h3.inspect}"

This preserves the Array key:

h3: {["orange", "seedless"]=>3, "apple"=>1, "banana"=>2}

How to create an array from hash replacing all of the keys and values with integers

First we make a range from 0 to the maximum key value (as an integer)
Then for each number we fetch the value in "a" at the corresponding key.
If the value is an array, we convert it into an array of integers
if not, convert it into an integer (unless it's false or nil).

a = {"0" => ["2", "3"], "1" => "4", "3" => "5"}
a = (0..(a.keys.map(&:to_i).max)).map do |v|
x = a[v.to_s]
x.is_a?(Array) ? x.map(&:to_i) : (x && x.to_i)
end

A better version that can handle a minimum key > "0"

a = a.values_at(*Range.new(*a.keys.minmax_by(&:to_i))).map do |v|
v.is_a?(Array) ? v.map(&:to_i) : (v && v.to_i)
end

a
=> [[2, 3], 4, nil, 5]

minmax returns an array that we explode into arguments to Range.new
We then explode that range into arguments for values_at.

[*Range.new(*["2","8"])]
=> ["2", "3", "4", "5", "6", "7", "8"]


Related Topics



Leave a reply



Submit