【问题标题】:sum array of hashes based on other fields in hash基于散列中其他字段的散列数组总和
【发布时间】:2010-12-06 17:31:01
【问题描述】:

我有一个如下所示的哈希数组:

[{:head_count=>150.5, :group=>"NW", :estimated_ship_date=>"201105", :yard=>"wcc"}, 
{:head_count=>201.0, :group=>"NW", :estimated_ship_date=>"201105", :yard=>"wcc"}, 
{:head_count=>103.5, :group=>"NW", :estimated_ship_date=>"201104", :yard=>"nyssa"}]

我希望从这些数据中创建一个哈希,如下所示:

{ 
  "wcc" => 
  { 
    "NW" => 
    { 
      "201105" => 351.5 # This being a sum
    }
  }
  "nyssa" =>
  {
    "NW" => 
    {
      "201104" => 103.5 # This being a sum
    }
  }
}

我不确定我还能提供哪些其他数据。

我尝试了收集,但不知道从哪里开始。

谢谢

【问题讨论】:

  • 总和是 351.5(不是 251.5),对吧?
  • 我希望我能将所有这些作为答案......很好的答案,有些我有点难以理解,但我相信它们是更高级的解决方案。

标签: ruby arrays hash multidimensional-array


【解决方案1】:

一个稍微不同的版本,使用哈希的默认过程来自动激活容器:

a = [
  {:head_count=>150.5, :group=>"NW", :estimated_ship_date=>"201105", :yard=>"wcc"}, 
  {:head_count=>201.0, :group=>"NW", :estimated_ship_date=>"201105", :yard=>"wcc"}, 
  {:head_count=>103.5, :group=>"NW", :estimated_ship_date=>"201104", :yard=>"nyssa"}
]

yards = Hash.new{ |h,yard|
  h[yard]=Hash.new{ |h,group|
    h[group]=Hash.new{ |h,est_date|
      h[est_date]=0
    }
  }
}
a.each do |h|
  yards[h[:yard]][h[:group]][h[:estimated_ship_date]] += h[:head_count]
end

p yards
#=> {"wcc"=>{"NW"=>{"201105"=>351.5}}, "nyssa"=>{"NW"=>{"201104"=>103.5}}}

【讨论】:

    【解决方案2】:

    我只是使用一个简单的循环。

    a = [{:head_count=>150.5, :group=>"NW", :estimated_ship_date=>"201105", :yard=>"wcc"}, 
    {:head_count=>201.0, :group=>"NW", :estimated_ship_date=>"201105", :yard=>"wcc"}, 
    {:head_count=>103.5, :group=>"NW", :estimated_ship_date=>"201104", :yard=>"nyssa"}]
    
    yards = {}
    a.each do |h|
      yard = yards[h[:yard]] ||= {}
      group = yard[h[:group]] ||= {}
      group[h[:estimated_ship_date]] ||= 0.0
      group[h[:estimated_ship_date]] += h[:head_count]
    end
    
    # yards => {"wcc"=>{"NW"=>{"201105"=>351.5}}, "nyssa"=>{"NW"=>{"201104"=>103.5}}}
    

    【讨论】:

      【解决方案3】:

      这是我的解决方案。

      yards = []
      a.select{|x| yards << x[:yard]}
      sol = Hash.new{|k,v| k[v] = Hash.new{|k,v| k[v] = {} } }
      yards.uniq.map do |x|
        a.select{|y| x == y[:yard]}.flatten.map do |z|
          sol[x][z[:group]][z[:estimated_ship_date]] = 0.0
          sol[x][z[:group]][z[:estimated_ship_date]] += z[:head_count]
        end
      end
      

      你的初始数组是 a。解决方案是溶胶。我希望这看起来可读

      【讨论】:

        【解决方案4】:
        x = [
        {:head_count=>100, :group=>"NE", :estimated_ship_date=>"201103", :yard=>"wcc"},
        {:head_count=>200, :group=>"NW", :estimated_ship_date=>"201104", :yard=>"wcc"},
        {:head_count=>300, :group=>"NW", :estimated_ship_date=>"201105", :yard=>"wcc"},
        {:head_count=>400, :group=>"NW", :estimated_ship_date=>"201105", :yard=>"wcc"},
        {:head_count=>500, :group=>"NW", :estimated_ship_date=>"201104", :yard=>"nyssa"}]
        
        p Hash[ x.group_by{ |i| i[:yard] }.map { |i,j|
            [i, Hash[ j.group_by { |i| i[:group] }.map { |i,j|
                [i, Hash[ j.group_by { |i| i[:estimated_ship_date] }.map{ |i,j|
                    [i, j.map{ |i| i[:head_count] }.inject(:+)]
                } ] ]
            } ] ]
        } ]
        

        {
            "wcc"=>
            {
                "NE"=>
                {
                    "201103"=>100
                },
                "NW"=>
                {
                    "201104"=>200,
                    "201105"=>700
                }
            },
            "nyssa"=>
            {
                "NW"=>
                {
                    "201104"=>500
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2012-08-03
          • 2015-04-21
          • 2011-12-25
          • 2014-05-19
          • 2011-08-15
          • 2012-06-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多