Project

General

Profile

Actions

Feature #19148

open

Define Hash#merge_sum as Hash#merge with sum block

Added by hgraham (Harry Graham) almost 2 years ago. Updated almost 2 years ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:110880]

Description

To merge two hashes whilst summing any common elements, we currently have to pass a block instructing how to add the elements from each hash:

items_1_counts = {:book => 4, :pen => 2, :pencil => 3}
items_2_counts = {:book => 2, :pencil => 6, :rubber => 11}

items_1_counts.merge(items_2_counts) { |_k, a, b| a + b }
=> {:book => 6, :pen => 2, :pencil => 9, :rubber => 11}

Having a method for this would (in my opinion) simplify it:

items_1_counts.merge_sum(items_2_counts)
=> { :book => 6, :pen => 2, :pencil => 9, :rubber => 11 }

Would this benefit many people?

This (merging two hashes whilst summing any common elements) seems to be a common scenario that many people raise on forums:

Updated by janosch-x (Janosch Müller) almost 2 years ago

naming, edge cases

merge_sum would be a confusing name IMO, because the method neither takes nor returns a (single) sum.

i'd suggest merge_tally, because it is in the same problem domain as Enumerable#tally.

merge_tally could then raise the same TypeErrors as tally in cases such as

{ a: 7 }.merge_tally(a: 'string')

other option

not sure about this, but maybe Hash could have a custom implementation of tally.

Ruby 3.1 introduced the option to pass an accumulator to tally:

hash = {}
hash = %w[a c d b c a].tally(hash)
hash # => {"a"=>2, "c"=>2, "d"=>1, "b"=>1}
hash = %w[b a z].tally(hash)
hash # => {"a"=>3, "c"=>2, "d"=>1, "b"=>2, "z"=>1}

this does not yet work for merging tallies because:

{ a: 7 }.tally # => {[:a, 7]=>1}
{ a: 7 }.tally(a: 3) # => {:a=>3, [:a, 7]=>1}

however, a Hash#tally override could make it act like this:

{ a: 7 }.tally # => {:a=>7}
{ a: 7 }.tally(a: 3) # => {:a=>10}

while that would be a breaking change, the current behavior that maps all KV pairs to 1 is a bit pointless and probably not consciously used by anyone?

Actions

Also available in: Atom PDF

Like0
Like0