## Introduction

• Let’s consider we have an array of the array as input. array elements basically represent order_id and product_id with that. So basically for order_id 1, product_id 2 was bought.
```[[1,2],[1,3],[2,3],[2,2],[3,1]]
```
• Now let’s say we want to calculate for each product_id which products were bought.
• Now this problem basically tells us to output something like Key Value, where the key is order_id and the value is a list of products.
• So for order_id 1 output would be -> { 1 => [2,3] }

Solution using external Hash

• One of the ways to write a solution is to create a Hash and initialize it with an array using a block
• Now when we iterate over our element using each we can add each product to its corresponding order_id which is key in our case and val is product_id.
• Hence for each key, we add value to our array using shovel operator << which is essentially appending or pushing an element to our array.
``` h = Hash.new { |h, k| h[k] = [] }

[[1,2],[1,3],[2,3],[2,2],[3,1]].each do |(key, val)|
h[key] << val
end
```
```irb(main):021:0> h
=> {1=>[2, 3], 2=>[3, 2], 3=>[1]}    #ouput
```

Improving solution by injecting Hash

• We can make our code more concise by using reduce operator instead of each.
• reduce operator takes an accumulator which we can initialize in reduce.
• Now, this is a good place to initialize our hash since we will need to collect all the product_id for a given key.
• Once we add the product_id, we return a hash so that at the end of the array we will be able to get our output.
```[[1,2],[1,3],[2,3],[2,2],[3,1]].reduce(Hash.new { |h,k|  h[k] = [] } ) do | hash, (key,val) |
hash[key] << val
hash
end

=> {1=>[2, 3], 2=>[3, 2], 3=>[1]} # ouptut
```

Some more examples

• Now we can use the above improvement in other use cases.
• For example, let’s say now the input array has product_id and a number of sales made at different points in time.
• Now we want to calculate how many of each product sold.
• Now our solution would require us to add the value of each key.
• We can again inject a hash map and initialize all the keys with the value 0
```[[1,2],[1,3],[2,3],[2,2],[3,1]].reduce(Hash.new { |h,k|  h[k] = 0 } ) do | hash, (key,val) |
hash[key] +=val
hash
end

=> {1=>5, 2=>5, 3=>1} # output
```
• We can also initialize hash with 0 simply by injecting Hash.new(0)
```[[1,2],[1,3],[2,3],[2,2],[3,1]].reduce(Hash.new(0) ) do | hash, (key,val) |
hash[key] +=val
hash
end

=> {1=>5, 2=>5, 3=>1} # output
```
• One of the alternative ways of achieving the same thing is using each_with_object method, which also allows us to inject hash with initialized value.
```[[1,2],[1,3],[2,3],[2,2],[3,1]].each_with_object(Hash.new(0)) do |(key,val), h|
h[key] += val
end
=> {1=>5, 2=>5, 3=>1} # output
```

## Conclusion

• In this article we looked at different options we have in ruby to initialize with the default value.
• reduce and each_with_object are good target methods to inject initialize objects when needed.
• Let me know in the comments if you know an additional approach.