Как мне сложить произведение двух значений на несколько объектов в Rails? - PullRequest
0 голосов
/ 15 мая 2018

Представьте, что у меня есть портфель 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)> 

Итак, по сути, используя приведенный выше код, я бы хотел сделать это:

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

Я хочу просто получить 19,800. В идеале я хотел бы сделать это очень рубиновым способом.

Если бы я просто суммировал все значения в 1 total_spend, я бы знал, что мог бы просто сделать: p.port_stocks.map(&:total_spend).sum, и это было бы так.

Но не уверен, как сделать нечто подобное, когда я сначала выполняю математическую операцию над каждым объектом, а затем складываю все продукты из всех объектов. Очевидно, это должно работать на 2 объекта или 500.

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Вы вправе использовать Array # map для перебора всех акций, но вместо того, чтобы суммировать все значения total_spend, вы можете рассчитать его для каждой акции. После вы суммируете все результаты и все готово:

p.port_stocks.map{|ps| ps.volume * ps.purchase_price}.sum

Или вы можете использовать Перечислимый # уменьшить , как это сделал SRack. Это вернет результат с одним шагом / итерацией.

0 голосов
/ 15 мая 2018

Лучший способ сделать это с помощью Rails - передать блок в sum, например:

p.port_stocks.sum do |port_stock|
  port_stock.volume * port_stock.purchase_price
end

, который использует метод, предназначенный для суммирования чисел, и имеет тенденцию быть очень быстрыми эффективен - особенно по сравнению с манипулированием данными перед вызовом прямой sum без блока.

Быстрый тест здесь обычно показывает, что он работает на ~ 20% быстрее, чем очевидные альтернативы.

Я не смог проверить, но попробуй, и он должен решить эту проблему для тебя.

Дай мне знать, как у тебя дела!


Просто быстрое обновление, поскольку вы также упомянули лучший способ Ruby, sum был введен в 2.4 , хотя в более старых версиях Ruby вы можете использовать уменьшать (также псевдоним inject):

p.port_stocks.reduce(0) do |sum, port_stock|
  sum + (port_stock.volume * port_stock.purchase_price)
end

Это не так эффективно, как sum, но я подумал, что я дам вам варианты:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...