Ruby中的实现合并方法

问题描述 投票:0回答:3

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

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

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

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

如何不使用合并方法来实现?

ruby merge hashmap array-merge
3个回答
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

0
投票

首先,std库中有Hash#merge

a = { "a" => 200, "b" => 100 }
b = { "b" => 100, "c" => 300 }
a.merge(b)  #=> {"a"=>200, "b"=>100, "c"=>300}

可以这样实现:

class Hash  # open existing Hash class to add a method
  def merge_method(another)
    another.each_pair { |k, v| self[k] = v }
    self # if you want to return the caller itself
  end  
end  

0
投票

我无法让自己将方法merge_method添加到类Hash中,不仅是因为它污染了一个核心类,而且还因为它仅适用于一小部分散列,而所有散列值都是数字。

一个可以refine Hash,就像@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

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

© www.soinside.com 2019 - 2024. All rights reserved.