From: janosch-x via ruby-core Date: 2022-12-25T16:52:58+00:00 Subject: [ruby-core:111424] [Ruby master Feature#19148] Define Hash#merge_sum as Hash#merge with sum block Issue #19148 has been updated by janosch-x (Janosch M�ller). ## 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`](https://ruby-doc.org/core-3.1.0/Enumerable.html#method-i-tally). `merge_tally` could then raise the same TypeErrors as `tally` in cases such as ```ruby { 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`: ```ruby 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: ```ruby { 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: ```ruby { 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? ---------------------------------------- Feature #19148: Define Hash#merge_sum as Hash#merge with sum block https://bugs.ruby-lang.org/issues/19148#change-100796 * Author: hgraham (Harry Graham) * Status: Open * Priority: Normal ---------------------------------------- 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: ```ruby 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: ```ruby 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: * https://stackoverflow.com/a/56190912 * https://stackoverflow.com/a/4453690 * https://codereview.stackexchange.com/a/136546 * https://www.appsloveworld.com/ruby/100/242/ruby-merge-sum-values-from-two-distincts-objects-having-the-same-keys -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/