是否有更优雅的方式将键/值对添加到哈希? (如果key == nil,则分配新的键/值,否则为现有键添加值)

时间:2016-05-03 13:28:41

标签: ruby hash

给定一个多项式表达式(例如3a+2c-4a)及其数组表示foo = [[3,'a'],[2,'c'],[-4,'a']],我通过创建一个哈希并按如下方式添加系数来简化表达式:

foo = [[3,'a'],[2,'c'],[-4,'a']]
foo_hash = {}
foo.each {|el| foo_hash.include?(el[1]) ? foo_hash[el[1]] = el[0] : foo_hash[el[1]] += el[0]}
foo_hash = {'a' => -1, 'c' => 2}

我的问题each块中的条件哈希赋值能否以更简洁的形式表达,避免重复?

3 个答案:

答案 0 :(得分:2)

您可以将Enumerable#injectHash#new

一起使用
foo.inject(Hash.new(0)) {|h, (n,a)| h[a]+= n; h  }
# => {"a" => -1, "c" => 2}

答案 1 :(得分:1)

这可以很好地利用Hash's initailizer中的默认值:

foo_hash = Hash.new(0)
# => {}
foo_hash["completely_new_key"]
# => 0

因此简洁的解决方案变为:

foo = [[3,'a'],[2,'c'],[-4,'a']]
foo_hash = Hash.new(0)
foo.each{|val, key| foo_hash[key] += val}
foo_hash
#  => {"a"=>-1, "c"=>2}

答案 2 :(得分:0)

或许merge!有一个块:

foo.each.with_object({}) { |p, h| h.merge!([p.reverse].to_h) { |_, x, y| x + y} }
#=> { "a" => -1, "c" => 2 }