Sum数组值最多可达一定总量

时间:2015-03-04 21:14:58

标签: ruby arrays sum

我有一系列哈希(已排序),如下所示:

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}

但是有这种方法还是其他方式?

1 个答案:

答案 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