Array to Hash Ruby

Array to Hash Ruby

a = ["item 1", "item 2", "item 3", "item 4"]
h = Hash[*a] # => { "item 1" => "item 2", "item 3" => "item 4" }

That's it. The * is called the splat operator.

One caveat per @Mike Lewis (in the comments): "Be very careful with this. Ruby expands splats on the stack. If you do this with a large dataset, expect to blow out your stack."

So, for most general use cases this method is great, but use a different method if you want to do the conversion on lots of data. For example, @Łukasz Niemier (also in the comments) offers this method for large data sets:

h = Hash[a.each_slice(2).to_a]

Convert Array to Hash while preserving Array index values in Ruby

Using Enumerable#each_with_index:

Hash[array.each_with_index.map { |value, index| [index, value] }]
# => {0=>"Adult", 1=>"Family", 2=>"Single", 3=>"Child"}

As @hirolau commented, each_with_index.map can also be written as map.with_index.

Hash[array.map.with_index { |value, index| [index, value] }]
# => {0=>"Adult", 1=>"Family", 2=>"Single", 3=>"Child"}

UPDATE

Alterantive that use Hash#invert:

Hash[array.map.with_index{|*x|x}].invert
# => {0=>"Adult", 1=>"Family", 2=>"Single", 3=>"Child"}
Hash[[*array.map.with_index]].invert
# => {0=>"Adult", 1=>"Family", 2=>"Single", 3=>"Child"}

Convert an array to hash, where keys are the indices

arr = ["one", "two", "three", "four", "five"]

x = Hash[(0...arr.size).zip arr]
# => {0=>"one", 1=>"two", 2=>"three", 3=>"four", 4=>"five"}

Ruby problem with returning hash value from an array of hashes

After reading your edited question, I see that there are a few conditions that weren't met with previous answers. I also see the main flaw in your code. Let's start with the flaw:

Your code seems a little overly complicated but it should work just fine if you make this one small change to the 5th line of the following section;

def find_favorite(array_of_hash_objects)
array_of_hash_objects.each do | hash |
hash.each do |key, val|
if key == :is_my_favorite? && val == true
return hash
end
end
end
return nil
end

Notice that I prepended the line with return. Your problem was that you were iterating through the array just fine but there was no container or method being initiated in order to store or return those results. Your second to last line was telling the method to return nil no matter what the results of the iteration were.


Now for my proposed solution:

I see now that your desired output should either be the single hash containing the true value or should be nil as opposed to the arrays resulting from the solutions mentioned above. I would probably do something like this;

def find_favorite(input)
output = nil
input.each{|h| h[:is_my_favorite?] ? output = h : nil}
output
end

arr_1 = [{ name: 'Ruby', is_my_favorite?: true }, { name: 'JavaScript', is_my_favorite?: false }, { name: 'HTML', is_my_favorite?: false }]
arr_2 = [{ name: 'Ruby', is_my_favorite?: false }, { name: 'JavaScript', is_my_favorite?: false }, { name: 'HTML', is_my_favorite?: false }]

find_favorite(arr_1) #=> {:name=>"Ruby", :is_my_favorite?=>true}
find_favorite(arr_2) #=> nil

Within the method definition, a container (output) is first defined with a default value of nil. We then iterate through the array and fill output with the hash containing a true value. Otherwise output returns the default value.

NOTE: You could optionally delete == true ? from the block but seeing as how I don't know how the original array is being created, I prefer to leave it in there to expressly communicate exactly what I'm looking for in a very human readable way. That's just my personal preference.

transform array of arrays in array of hash

array = [
[ 1, "name1" ],
[ 2, "name2" ],
[ 3, "name3" ],
[ 4, "name4" ]
]
array.map { |e| ['id', 'name'].zip(e).to_h }
#⇒ [
# {"id"=>1, "name"=>"name1"},
# {"id"=>2, "name"=>"name2"},
# {"id"=>3, "name"=>"name3"},
# {"id"=>4, "name"=>"name4"}
# ]

The only interesting here is Enumerable#zip, that “merges” arrays.

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

Adding new keys to a Array Of Hashes

I would probably:

  1. Use map to iterate over the elements in list and build a new array at the same time
  2. Since each element is a hash with one item, destruct that into a key and value
  3. Build the new hash in the correct format
new_list = list.map do |hash|
# e.g. key = "Mary", value = "Die Hard"
key, value = hash.first

{name: key, film: value}
end

This assumes that each hash in the list will have only one item (as you've shown in your example in the question) - you may want to validate this elsewhere, since this solution would ignore any other items in the hash past the first.

Ruby array to hash: each element the key and derive value from it

Ruby's each_with_object method is a neat way of doing what you want

['a', 'b'].each_with_object({}) { |k, h| h[k] = k.upcase }


Related Topics



Leave a reply



Submit