如何在Rails中的多个对象之间求和两个值的乘积?

mar*_*ion 0 ruby ruby-on-rails ruby-on-rails-5

想象一下,我有一个p有2股票的投资组合port_stocks.我想要做的是对每个进行计算port_stock,然后总结所有结果.

[60] pry(main)> p.port_stocks
=> [#<PortStock:0x00007fd520e064e0
  id: 17,
  portfolio_id: 1,
  stock_id: 385,
  volume: 2000,
  purchase_price: 5.9,
  total_spend: 11800.0>,
 #<PortStock:0x00007fd52045be68
  id: 18,
  portfolio_id: 1,
  stock_id: 348,
  volume: 1000,
  purchase_price: 9.0,
  total_spend: 9000.0>]
[61] pry(main)> 
Run Code Online (Sandbox Code Playgroud)

所以,从本质上讲,使用上面的代码我想这样做:

ps = p.port_stocks.first #(`id=17`)
first = ps.volume * ps.purchase_price # 2000 * 5.9 = 11,800

ps = p.port_stocks.second #(`id=18`)
second = ps.volume * ps.purchase_price # 1000 * 9.0 = 9,000

first + second = 19,800
Run Code Online (Sandbox Code Playgroud)

我想简单地说19,800.理想情况下,我想以非常Ruby的方式做到这一点.

如果我只是简单地总结1中的所有值total_spend,我知道我可以做到:p.port_stocks.map(&:total_spend).sum那就是那个.

但是当我第一次对每个对象进行数学运算时,不确定如何做类似的事情,然后将所有对象中的所有产品相加.这显然适用于2个物体或500个物体.

SRa*_*ack 6

使用Rails执行此操作的最佳方法是将块传递给sum,如下所示:

p.port_stocks.sum do |port_stock|
  port_stock.volume * port_stock.purchase_price
end
Run Code Online (Sandbox Code Playgroud)

它使用专用于总计数字的方法,并且往往非常快速和有效 - 特别是与在sum没有块的情况下调用直线之前操纵数据相比.

这里的快速基准测试通常表明它比明显的替代品快20%.

我无法测试,但尝试一下,它应该为你解决这个问题.

让我知道你是怎么办的!


只是快速更新,因为你还提到了最好的Ruby方式,在2.4sum引入,虽然在旧版本的Ruby上你可以使用reduce(也有别名inject):

p.port_stocks.reduce(0) do |sum, port_stock|
  sum + (port_stock.volume * port_stock.purchase_price)
end
Run Code Online (Sandbox Code Playgroud)

这不是那么高效sum,但我想我会给你选择:)