我有一系列哈希(已排序),如下所示:
testArray = [{price: 540, volume: 12},
{price: 590, volume: 18},
{price: 630, volume: 50}]
现在我想计算一定总量的平均值。假设有人想购买40件,他希望这是最便宜的方式。这意味着平均价格为(540 * 12 + 590 * 18 + 630 * 50)/ 40个单位。
我的第一次尝试是:
testArray.each do |priceHash|
@priceArray << priceHash.fetch(:price)
@volumeArray << priceHash.fetch(:volume)
end
def calculateMiddlePrice(priceArray, volumeArray, totalAmount)
result = 0
# Here some crazy wild magic happens
(0...volumeArray.count).inject(0) do |r, i|
if (volumeArray[0..i].inject(:+)) < totalAmount
r += volumeArray[i]*priceArray[i]
elsif volumeArray[0..i-1].inject(:+) < totalAmount && volumeArray[0..i].inject(:+) >= totalAmount
theRest = volumeArray[i] - (volumeArray[0..i].inject(:+) - totalAmount)
r += theRest * priceArray[i]
elsif volumeArray[0] > totalAmount
r = totalAmount * priceArray[0]
end
result = r
end
result
end
现在我甚至不确定它为什么会起作用,但确实如此。然而,这个绝对荒谬的代码在我眼中。
我的第二个想法是在达到总量时削减我的testArray。代码看起来更好
testAmount = 31
def returnIndexForSlice(array, amount)
sum = 0
array.each_index do |index|
p sum += array[index][:volume]
if sum >= amount
return index+1
end
end
end
testArray.slice(0,returnIndexForSlice(testArray, testAmount))
不过,如果你能说的话,这只是感觉不对,“红宝石”。我检查了几乎每个数组类的方法,用bsearch来玩,但是我无法找到解决问题的优雅方法。
我的想法是这样的:
amountToCheck = 31
array.some_method.with_index {|sum, index| return index if sum >= amountToCheck}
但是有这种方法还是其他方式?
答案 0 :(得分:3)
鉴于您的价格阵列哈希:
prices = [ {price: 540, volume: 12},
{price: 590, volume: 18},
{price: 630, volume: 50}]
您可以分两步计算结果。
def calc_price(prices, amount)
order = prices.flat_map{|item| [item[:price]] * item[:volume] } #step 1
order.first(amount).reduce(:+)/amount #step 2
end
步骤1:创建一个包含每个项目的数组(如果价格没有排序,则必须添加sort_by
子句)。换句话说,将价格扩展为包含12个540,18 590等的数字数组。这使用Ruby的数组重复方法:[n] * 3 = [n, n, n]
。
第2步:平均前n个元素
结果:
calc_price(prices, 40)
=> 585