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

Ruby on rails Ruby哈希数组-每个财政年度,ruby-on-rails,arrays,ruby,hash,Ruby On Rails,Arrays,Ruby,Hash,我有一个事务数组,其中包含事务哈希。我想循环遍历事务哈希数组,并为每个财政年度计算利息和本金的总和。然后需要将它们添加到各自的阵列中,按财政年度分组,如下所示 简言之: 每个财政年度: 1.对兴趣键的值求和 2.创建散列 3.将散列添加到相应的数组中 4.对主值重复上述步骤 我在第一步上有点卡住了:每个财政年度都要做x-任何帮助都将不胜感激 Ruby 2.3.1 给定 我想计算一下 @interest_totals = [ {"financial_year" => "2017",

我有一个事务数组,其中包含事务哈希。我想循环遍历事务哈希数组,并为每个财政年度计算利息和本金的总和。然后需要将它们添加到各自的阵列中,按财政年度分组,如下所示

简言之:

每个财政年度:

1.对兴趣键的值求和

2.创建散列

3.将散列添加到相应的数组中

4.对主值重复上述步骤

我在第一步上有点卡住了:每个财政年度都要做x-任何帮助都将不胜感激

Ruby 2.3.1

给定

我想计算一下

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


您可以按年份对这些值进行分组,然后将本金和利息金额相加

@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 }]

使用
inject
reduce
使用对象的每个\u
。我在下面使用了带有_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)>}

我建议您首先计算以下散列

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"}}
它使用(aka
merge!
)的形式,并使用一个块来确定合并的两个哈希中存在的键的值。有关详细信息,请参阅文档,特别是块变量的值,
\uucode>,
o
n
k
oo
nn
。(在第一个块中,我使用了一个下划线作为公共键,表示在块计算中未使用该键。)

这种中间解决方案的一个优点是,如果添加(“余额”),删除或重命名关键字(除“财务年度”外),则无需更改

现在可以轻松地构造其他对象。比如说,

@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"}]   

虽然你的排版引号看起来很漂亮,但是你必须使用
“…”
“…”
而不是Ruby中的
“…”
“…”
。我编辑了这个问题以更正@Stefan发现的错误。詹姆斯,请在发帖前一直运行你的代码(比如IRB)以确保它是正确的。Will do@CarySwoveland-谢谢
@interest_sum = interests.map do |interest|
  Hash[['financial_year', 'total'].zip(interest)]
end
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"}}
@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"}]