Ruby哈希数组 - 每个财政年度

时间:2017-01-11 05:50:29

标签: ruby-on-rails arrays ruby hash

我有一个包含事务哈希的事务数组。我想循环遍历事务哈希数组,并且对于每个财政年度,将利息和主要值相加。然后需要将它们添加到各个阵列中,按财务年度分组,如下所示。

简而言之:

每个财政年度:

1.Sum the interest keys of the interest键

2.创建哈希

3.将哈希添加到相应的数组

4.重复主要值

我在第一步有点困惑:对于每个财政年度,做x - 任何帮助都将受到赞赏。

Ruby 2.3.1

鉴于

 @transactions = [
  {"interest" => "120.00", "principal" => "250", "financial_year" => "2017"},
  {"interest" => "120.00", "principal" => "250", "financial_year" => "2017"},
  {"interest" => "120.00", "principal" => "250", "financial_year" => "2017"},
  {"interest" => "120.00", "principal" => "250", "financial_year" => "2018"},
  {"interest" => "120.00", "principal" => "250", "financial_year" => "2018"},
  {"interest" => "120.00", "principal" => "250", "financial_year" => "2019"},
  {"interest" => "120.00", "principal" => "250", "financial_year" => "2019"}
 ]

我想计算

 @interest_totals = [
    {"financial_year" => "2017", "total" => "360"}
    {"financial_year" => "2018", "total" => "240"}
    {"financial_year" => "2019", "total" => "240"}
 ]

 @principal_totals = [
    {"financial_year" => "2017", "total" => "750"}
    {"financial_year" => "2018", "total" => "500"}
    {"financial_year" => "2019", "total" => "500"}
 ]

3 个答案:

答案 0 :(得分:2)

使用injectreduceeach_with_object。我使用下面的each_with_object,以便我可以在一次迭代中计算两者的总和

interests, principals = @transactions.each_with_object([Hash.new(0), Hash.new(0)]) do |transaction, (interests, principals)|
  interests[transaction['financial_year']] += transaction['interest'].to_d
  principals[transaction['financial_year']] += transaction['principal'].to_d
end

p interests
# {"2017"=>#<BigDecimal:7fd1c6cc20f0,'0.36E3',9(18)>, "2018"=>#<BigDecimal:7fd1c6cc1d30,'0.24E3',9(18)>, "2019"=>#<BigDecimal:7fd1c6cc1970,'0.24E3',9(18)>}

p principals
# {"2017"=>#<BigDecimal:7fd1c6cc2050,'0.75E3',9(18)>, "2018"=>#<BigDecimal:7fd1c6cc1c90,'0.5E3',9(18)>, "2019"=>#<BigDecimal:7fd1c6cc18d0,'0.5E3',9(18)>}

这将为您提供一个哈希,其中年份是关键,值是总数。如果您确实需要一组哈希值,请使用zip

@interest_sum = interests.map do |interest|
  Hash[['financial_year', 'total'].zip(interest)]
end

答案 1 :(得分:0)

您可以按年度对值进行分组,然后将原则和利息金额相加

@interest_totals =  @transactions.group_by{|a| a["financial_year"]}.map{|k, v| {"financial_year" => k, "total" => v.map{|e|e["interest"].to_i}.sum}}

#=> [{ "financial_year" => "2017", "total" => 360 },
#=>  { "financial_year" => "2018", "total" => 240 },
#=>  { "financial_year" => "2019", "total" => 240 }]

@principal_totals = @transactions.group_by{|a| a["financial_year"]}.map{|k, v| {"financial_year" => k, "total" => v.map{|e|e["principal"].to_i}.sum}}

#=> [{ "financial_year" => "2017", "total" => 750 },
#=>  { "financial_year" => "2018", "total" => 500 },
#=>  { "financial_year" => "2019", "total" => 500 }]

答案 2 :(得分:0)

我建议您先计算以下哈希值。

h = @transactions.each_with_object({}) do |g,h|
  h.update(g["financial_year"]=>g.reject { |k,_| k=="financial_year" }) do |_,o,n|
    o.merge(n) { |_,oo,nn| (oo.to_i + nn.to_i).to_s }
  end
end
  #=> {"2017"=>{"interest"=>"360", "principal"=>"750"},
  #    "2018"=>{"interest"=>"240", "principal"=>"500"},
  #    "2019"=>{"interest"=>"240", "principal"=>"500"}}

这使用Hash#update(aka merge!)和Hash#merge的形式,它使用一个块来确定合并的两个哈希中存在的键的值。有关详细信息,请参阅文档,尤其是块变量的值,_onkoonn。 (在第一个块中,我使用公共密钥的下划线表示它未在块计算中使用。)

这种中间解决方案的一个优点是,如果添加了键(&#34; financial_year&#34;除外)(&#34;余额&#34;,比如说),删除或删除或不需要更改重命名。

您现在可以轻松构建其他对象。例如,

@interest_totals = h.map { |year,v| {"financial_year"=>year, "total"=> v["interest"] } }
  #=> [{"financial_year"=>"2017", "total"=>"360"},
  #    {"financial_year"=>"2018", "total"=>"240"},
  #    {"financial_year"=>"2019", "total"=>"240"}]