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
Carrierwave Crop Specific Version
How to Convert an Existing Rails 3 Application into an Engine
Cleanest Way to Create a Hash from an Array
Define a Method That Is a Closure in Ruby
How to Use One Line Regular Expression to Get Matched Content
Rails: Creating a Custom Data Type/Creating a Shorthand
Ruby: How to Pass All Parameters and Blocks Received by One Method to Another
Sort an Array of Strings by Their Integer Values
Spinach VS Cucumber for Bdd in Rails
Ruby: Cannot Parse Excel File Exported as CSV in Os X
In Ruby How to Generate a Long String of Repeated Text
Generating Unique Token on the Fly with Rails
Ruby Method with Maximum Number of Parameters
Add Comment to User and Post Models (Ruby on Rails)
Ruby Easy Search for Key-Value Pair in an Array of Hashes
Rails Plugin for API Key + Secret Key Signing