Home > Blockchain >  Given an array of hashes modify each one to include a key value combination of another hash
Given an array of hashes modify each one to include a key value combination of another hash

Time:11-28

Example 1:

array_of_hashes = [{"name"=>"bob", "age"=>30}, {"name"=>"bart", "age"=>35}]

metadata_hash = {"likes"=>["apples", "oranges"], "dislikes"=>["cold"]}

How would you get to this output:

[{"name"=>"bob", "age"=>30, "likes"=>"apples", "dislikes"=>"cold"},
 {"name"=>"bob", "age"=>30, "likes"=>"oranges", "dislikes"=>"cold"},
 {"name"=>"bart", "age"=>35, "likes"=>"apples", "dislikes"=>"cold"},
 {"name"=>"bart", "age"=>35, "likes"=>"oranges", "dislikes"=>"cold"}]

Example 2:

array_of_hashes = [{"name"=>"bob", "age"=>30}, {"name"=>"bart", "age"=>35}]
metadata_hash = {"likes"=>["apples", "oranges"], "dislikes"=>["cold"], "courses"=>["science", "history"]}

Expected Output:

[{"name"=>"bob", "age"=>30, "likes"=>"apples", "dislikes"=>"cold", "courses"=>"science"},
 {"name"=>"bob", "age"=>30, "likes"=>"oranges", "dislikes"=>"cold", "courses"=>"history"},
 {"name"=>"bob", "age"=>30, "likes"=>"oranges", "dislikes"=>"cold", "courses"=>"science"}
 {"name"=>"bob", "age"=>30, "likes"=>"apples", "dislikes"=>"cold", "courses"=>"history"},
 {"name"=>"bart", "age"=>35, "likes"=>"apples", "dislikes"=>"cold", "courses"=>"science"},
 {"name"=>"bart", "age"=>35, "likes"=>"oranges", "dislikes"=>"cold", "courses"=>"history"},
 {"name"=>"bart", "age"=>35, "likes"=>"oranges", "dislikes"=>"cold", "courses"=>"science"}
 {"name"=>"bart", "age"=>35, "likes"=>"apples", "dislikes"=>"cold", "courses"=>"history"}]

CodePudding user response:

arr = [{"name"=>"bob", "age"=>30}, {"name"=>"bart", "age"=>35}]

meta_hash = {"likes"=>["apples", "oranges"], "dislikes"=>["cold"],
             "courses"=>["science", "history"]} 

You can compute the desired result as follows.

keys, (first_value, *rest_of_values) = metadata_hash.to_a.transpose
  #=> [["likes", "dislikes", "courses"], [["apples", "oranges"],
       ["cold"], ["science", "history"]]]

Ergo,

keys
  #=> ["likes", "dislikes", "courses"]
first_value
  #=> ["apples", "oranges"]
rest_of_values = ["cold"], ["science", "history"]]
a = first_value.product(*rest_of_values).map { |arr| keys.zip(arr).to_h }
  #=> [{"likes"=>"apples", "dislikes"=>"cold", "courses"=>"science"},
  #    {"likes"=>"apples", "dislikes"=>"cold", "courses"=>"history"},
  #    {"likes"=>"oranges", "dislikes"=>"cold", "courses"=>"science"},
  #    {"likes"=>"oranges", "dislikes"=>"cold", "courses"=>"history"}]
array_of_hashes.flat_map { |h| a.map { |g| h.merge(g) }}
  #=> [{"name"=>"bob", "age"=>30, "likes"=>"apples", "dislikes"=>"cold", "courses"=>"science"},
  #    {"name"=>"bob", "age"=>30, "likes"=>"apples", "dislikes"=>"cold", "courses"=>"history"},
  #    {"name"=>"bob", "age"=>30, "likes"=>"oranges", "dislikes"=>"cold", "courses"=>"science"},
  #    {"name"=>"bob", "age"=>30, "likes"=>"oranges", "dislikes"=>"cold", "courses"=>"history"},
  #    {"name"=>"bart", "age"=>35, "likes"=>"apples", "dislikes"=>"cold", "courses"=>"science"},
  #    {"name"=>"bart", "age"=>35, "likes"=>"apples", "dislikes"=>"cold", "courses"=>"history"},
  #    {"name"=>"bart", "age"=>35, "likes"=>"oranges", "dislikes"=>"cold", "courses"=>"science"},
  #    {"name"=>"bart", "age"=>35, "likes"=>"oranges", "dislikes"=>"cold", "courses"=>"history"}]

The first step in the calculation of a is the following.

first_value.product(*rest_of_values)
  #=> [["apples", "cold", "science"], ["apples", "cold", "history"],
  #    ["oranges", "cold", "science"], ["oranges", "cold", "history"]]

See Array#product, Enumerable#flat_map and Hash#merge. Array decomposition was employed in the calculation of keys, first_value and rest_of_values. See this article (for example) for more information on that subject.

  •  Tags:  
  • ruby
  • Related