Search code examples
rubymergehashmaparray-merge

Implement merge method in ruby


I'm trying to implement merge method in my code.

A = { "a" => 200, "b" => 100 }
B = { "b" => 100, "c" => 300 }

So when I call A.merge_method(B) in my main function, it should return

A.merge_method(B) #=> {"a"=>200, "b"=>200, "c"=>300}

How can I implement without using merge method?


Solution

  • Here is the general idea: collect all the keys of any hashes to be merged, then for each of the keys, collect the values in all the hashes that have that key, and sum them.

    module HashWithMergeReduce
      refine Hash do
        def merge_reduce(*others, &op)
          hashes = [self, *others]
          hash_keys = hashes.map(&:keys).inject(Set.new, &:+)
          hash_keys.each do |key|
            hashes_with_key = hashes.select { |hash| hash.has_key?(key) }
            self[key] = hashes_with_key.map { |hash| hash[key] }.reduce(&op)
          end
          self
        end
      end
    end
    
    module TestHashWithMergeReduce
      using HashWithMergeReduce
      a = { "a" => 200, "b" => 100 }
      b = { "b" => 100, "c" => 300 }  
      puts a.merge_reduce(b, &:+)
      # => {"a"=>200, "b"=>200, "c"=>300}
    end