takes in a dictionary key and return an array filled with the appropriate values of the keys

Viewed 46

Given the hash

person = { 
  "cats"=> 2,
  "dogs"=> 1
}

I wish to construct the array

["cats", "cats", "dogs"]

"cats" appears twice because person["cats"] #=> 2. For the same reason "dogs" appears once. If the hash had a third key-value pair "pigs"=>3, I would want to return the array

["cats", "cats", "dogs", "pigs", "pigs", "pigs"]

I tried the following code.

arr = person.to_a    
i = 0
new_arr = []
while i < arr.length
  el = arr[i][0] 
  final = [new_arr << el]
  print final.flatten
  i += 1
end

This displays

["cats"]["cats", "dogs"] => nil

but does not seem to return a value.

new_arr
  #=> ["cats", "dogs"]

As you see, I am not getting the answer I wanted and do not understand why print displays what I show above.

I would like to know what is wrong with my code and what would be a better way of doing this.

2 Answers

flat_map method will flatten multiple arrays into one

Array operator * creates array with multiple values

result = person.flat_map {|key, value| [key] * value}

# => ["cats", "cats", "dogs"]

Ruby has a lot of nice methods to work with collections. I believe it is better to use them instead of while loop. You can iterate through the hash using inject method. The first parameter in the block is the resulting array, that accumulates the result of each iteration, the second is a key/value pair.

person.inject([]) do |array, (key, value)|
  array + Array.new(value, key)
end

Or it can be rewritten as a one line.

person.inject([]) { |array, (key, value)| array + Array.new(value, key) }
Related