总和数组值达到一定总量 [英] Sum array values up to a certain total amount

查看:119
本文介绍了总和数组值达到一定总量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有哈希数组(排序),像这样:

I've got an array of hashes (sorted), something like this:

testArray = [{price: 540, volume: 12},
            {price: 590, volume: 18},
            {price: 630, volume: 50}]

现在我要计算的平均值达到一定总量。比方说,有人想购买40件,他希望它最便宜的方式。这将意味着平均价格(540 * 12 + 590 * 18 + 630 * 50)/ 40单位的钱。

Now I want to calculate the mean value up to certain total volume. Let's say someone wants to buy 40 pieces and he wants it the cheapest way. It would mean an average price of (540*12+590*18+630*50)/40 money units.

我的第一次尝试以下操作:

My first attempt is following:

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

现在我也不知道为什么它的工作原理,但它确实。然而,这绝对荒谬code在我的眼前。

Right now I'm not even sure why it works, but it does. However this absolutely ridiculous code in my eyes.

我的第二个想法是把我的testArray达到总金额的时候。在code看起来更好

My second thought was to cut my testArray when the total amount is achieved. The code looks better

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))

不过,这只是不觉得正确的,rubyish如果你能这么说。我检查了几乎每一个方法数组类,用bsearch发挥各地,但我不能找出解决我的问题的一个非常优雅的方式。

Still, this just doesn't feel that right, "rubyish" if you could say so. I checked almost every method for array class, played around with bsearch, however I can't figure out a really elegant way of solving my problem.

什么是穿越我的脑海里是这样的事情:

What's crossing my mind is something like that:

amountToCheck = 31
array.some_method.with_index {|sum, index| return index if sum >= amountToCheck}

但是,有没有这样的方法或任何其他方式?

But is there such method or any other way?

推荐答案

鉴于你的价格哈希数组:

Given your prices array of hashes:

prices = [  {price: 540, volume: 12},
            {price: 590, volume: 18},
            {price: 630, volume: 50}]

您可以在2个步骤计算您的结果​​。

You can calculate your result in 2 steps.

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 条款)。换句话说,展开价格进入包含十二540的,18 590的等数字数组这将使用Ruby的数组重复的方法: [N] * 3 = [N,N,N]

Step 1: Create an array with each individual item in it (if the prices aren't sorted, you have to add a sort_by clause). In other words, expand the prices into a numeric array containing twelve 540's, 18 590's, etc. This uses Ruby's array repetition method: [n] * 3 = [n, n, n].

第二步:平均前n个元素

Step 2: Average the first n elements

结果:

calc_price(prices, 40)
=> 585

这篇关于总和数组值达到一定总量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆