【问题标题】:Implement merge method in ruby在 ruby​​ 中实现合并方法
【发布时间】:2020-02-14 23:02:37
【问题描述】:

我正在尝试在我的代码中实现合并方法。

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

所以当我在主函数中调用A.merge_method(B) 时,它应该返回

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

不使用merge方法如何实现?

【问题讨论】:

    标签: ruby merge hashmap array-merge


    【解决方案1】:

    我无法将merge_method 方法添加到Hash 类中,不仅因为它污染了一个核心类,还因为它只适用于一小部分哈希值,所有值的哈希值是数字。

    可以refineHash,就像@Amadan 所做的那样,但我认为简单地创建一个类似于模块方法的方法更有意义,该方法表现为函数(例如,Math::sqrt),它采用所有哈希值作为论据。

    def sum_values_by_key(*hashes)
      hashes.each_with_object(Hash.new(0)) { |g,h| g.each { |k,v| h[k] += v } }
    end
    

    sum_values_by_key({ "a" => 200, "b" => 100 }, { "b" => 100, "c" => 300 })
      #=> {"a"=>200, "b"=>200, "c"=>300}
    
    sum_values_by_key({ "a" => 200, "b" => 100 }, { "b" => 100, "c" => 300 },
                      { "a" => 150, "c" => 250 }) 
      #=> {"a"=>350, "b"=>200, "c"=>550}
    

    这使用Hash::new 的形式定义一个默认值,这里是零。表达式:

    h[k] += v
    

    扩展到:

    h[k] = h[k] + v
    

    如果此哈希已定义h = Hash.new(0) 并且h 有一个键k,则计算相等右侧的h[k] 以返回k 的值。但是,如果h 没有键k,则右侧的h[k] 返回默认值零,变为:

    h[k] = 0 + v
    

    我还更改了方法名称以使其更有意义。

    【讨论】:

      【解决方案2】:

      这里是一般的想法:收集所有要合并的哈希的所有键,然后对于每个键,收集具有该键的所有哈希中的值,并将它们相加。

      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
      

      【讨论】:

      • 我收到此错误:':未初始化的常量 TestHashWithMergeReduce::HashWithMergeReduce(名称错误)
      • 这很奇怪,它是在它上面定义的。 (如果你在 Irb 中执行它,它应该可以工作;如果你在一个文件中执行它,你需要require 'set';但是我看到你得到错误的唯一方法是你只执行了下半部分我的代码。)显然,您也可以在不经过改进的情况下编写它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多