ruby life questions
ruby life questions

Reputation: 129

Update hash value array from other array

I have a hash:

{
  "grey" => ["anf_94748_01_prod1", "anf_94748_01_model1", "anf_94748_01_model2"],
  "heather blue" => ["anf_106537_01_prod1", "anf_106537_01_model1", "anf_106537_01_model2"],
  "indigo" => [],
  "dark grey" => ["anf_94747_01_prod1"]
}

How can I replace its values according to an array of image ids:

[317, 318, 319, 320, 340, 358, 365]

If hash array is empty, then skip it and go to the next hash key, and assign id to that image. Desired output will be:

{
  "grey" => [317, 318, 319],
  "heather blue" => [320, 340, 358],
  "indigo" => [],
  "dark grey" => [365]
}

Upvotes: 1

Views: 51

Answers (3)

Cary Swoveland
Cary Swoveland

Reputation: 110675

As a variant of @sawa's answer, if you do not wish to mutate h, the OP's example hash, you could do this:

a = [317, 318, 319, 320, 340, 358, 365]

h.merge(h) { |_,v| a.shift(v.size) }
   #=> {"grey"=>[317, 318, 319], "heather blue"=>[320, 340, 358],
   #    "indigo"=>[], "dark grey"=>[365]

This uses the form of Hash#merge that employs a block to determine the values of keys present in both hashes, which here is all keys.

Upvotes: 1

sawa
sawa

Reputation: 168091

h = {
  "grey" => ["anf_94748_01_prod1", "anf_94748_01_model1", "anf_94748_01_model2"],
  "heather blue" => ["anf_106537_01_prod1", "anf_106537_01_model1", "anf_106537_01_model2"],
  "indigo" => [],
  "dark grey" => ["anf_94747_01_prod1"]
}
a = [317, 318, 319, 320, 340, 358, 365]

h.each_value{|v| v.map!{a.shift}}
# =>
# {
#   "grey"=>[317, 318, 319],
#   "heather blue"=>[320, 340, 358],
#   "indigo"=>[],
#   "dark grey"=>[365]
# }

Upvotes: 3

spike
spike

Reputation: 10004

reduce is a good function for taking moving through a data structure while accumulating some result.

imgs = [317, 318, 319, 320, 340, 358, 365]
input = {"grey"=>["anf_94748_01_prod1", "anf_94748_01_model1", "anf_94748_01_model2"], "heather blue"=>["anf_106537_01_prod1", "anf_106537_01_model1", "anf_106537_01_model2"], "indigo"=>[], "dark grey"=>["anf_94747_01_prod1"]}

input.reduce({}) { |acc, (k, xs)| acc[k] = imgs.shift(xs.count); acc}

# => {"grey"=>[317, 318, 319], "heather blue"=>[320, 340, 358], "indigo"=>[], "dark grey"=>[365]} 

Upvotes: 0

Related Questions