【问题标题】:Nested Hash sum嵌套哈希和
【发布时间】:2015-04-16 23:24:45
【问题描述】:

我有这个哈希

{
    19132=>{
        :occurences=>34,
        :name=>"bar"
    },
    19133=>{
        :occurences=>19,
        :name=>"foo"
    }
}

我想在每个键(19132 和 19133)上的新键(为什么不是 total)中找到出现次数 (34+19) 的添加。

我有类似的东西:

my_hash = {19132=>{:occurences=>34, :name=>"bar"}, 19133=>{:occurences=>19, :name=>"foo"}}
my_hash.values.inject{|memo, el| memo.merge(el){|k, old_v, new_v| old_v + new_v if k.is_a?(Numeric)}}

我找到了一些帮助 Here,但我被合并卡住了。我什至不知道这种方法是否可以解决我的问题。

【问题讨论】:

  • 你能发布你想要的输出吗?
  • 我不推荐它,但可以在不参考键 :occurrences(注意两个 r)的情况下计算总数:hash.values.map(&:values).flatten.reduce(0) { |tot, v| tot + v.to_i } #=> 53

标签: ruby hash


【解决方案1】:

我尝试分两步实现:求总数和合并总数。

hash = {19132=>{:occurences=>34, :name=>"bar"}, 19133=>{:occurences=>19, :name=>"foo"}}

total = hash.collect(&:first).sum
# => 38265

hash.each{|h| h[1].merge!({"total" => total})}
# => {19132=>{:occurences=>34, :name=>"bar", "total"=>38265}, 19133=>{:occurences=>19, :name=>"foo", "total"=>38265}}

【讨论】:

    【解决方案2】:

    首先,遍历所有内部哈希并计算总数:

    total = h.values.inject(0) { |total, hash| total + hash[:ocurrences] }

    然后,将总数添加到内部哈希中:

    h.keys.each{|k| h[k][:total] = total}

    【讨论】:

      【解决方案3】:
      sum = h.values.inject(0) {|sum, h| sum + h[:occurences] }
      # => 53 
      h.map {|k, v| v[:total] = sum; [k,v]}.to_h
      # => { 19132=>{:occurences=>34, :name=>"bar", :total=>53},
      #      19133=>{:occurences=>19, :name=>"foo", :total=>53} }
      

      【讨论】:

      • 您可以通过将Hash#values 替换为枚举器Hash#each_value 来避免创建临时数组。
      • @CarySwoveland,但是这不会为 Hash 中的每个值计算总和吗?
      • 对于迟到的回复,我深表歉意。我不确定我是否理解您的要求,但我不建议您更改仅引用:occurrences 的块。注意Enumerator.included_modules.first #=> Enumerable.
      【解决方案4】:

      你可以这样做:

      tot = h.each_value.reduce(0) { |t, g| t + g[:occurrences] }
      h.merge(h) { |*_,g| g.merge("total"=>tot) }
        # => {19132=>{:occurrences=>34, :name=>"bar", "total"=>53},
        #     19133=>{:occurrences=>19, :name=>"foo", "total"=>53}}
      

      这不会改变原始哈希:

      h #=> {19132=>{:occurrences=>34, :name=>"bar"},
        #    19133=>{:occurrences=>19, :name=>"foo"}} 
      

      如果您想在原地更改h

      h.merge!(h) { |*_,g| g.merge!("total"=>tot) }
      

      有效,但是:

      h.each_value { |g| g["total"] = tot }
      

      更好。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-14
        • 1970-01-01
        • 1970-01-01
        • 2013-04-30
        相关资源
        最近更新 更多