javascript计算价格的小算法

javascript little algorithm to calculate prices

本文关键字:算法 计算 javascript      更新时间:2023-09-26

我正在开发一个小网站,我有20种产品在销售。

每周我都想计算每种产品的新价格,考虑到每种产品完成的销售数量,但遵循两条规则:

  • 20种产品的价格总和必须始终为100欧元
  • 我希望每个产品都是整数(没有小数)或.5,我的意思是,一个产品的价格可以是7、8、9、7.5或8.5,但不能是8.3或7.1

让我们举一个例子,但用4种产品来简化:

本周销售:

product_id  sells
----------  ------
     1       45
     2       31
     3       12
     4       62

好的,那么总销售额是150。

如果我把这100欧元除以150次销售,我得到0.667欧元/次销售。所以如果我把每个产品乘以这个值,我得到的是:

product_id  sells  raw_price_next_week
----------  ------  -------------------
     1       45             30.015
     2       31             20.677
     3       12             8.004
     4       62             41.354

然后,我需要将这些raw_price标准化,同时考虑到我之前提到的第二条规则,即获得每个raw_value的最接近的0.5倍。。。

product_id  sells  raw_price_next_week    final_price
----------  ------  -------------------    ------------
     1       45             30.015             30
     2       31             20.677             20.5
     3       12             8.004              8
     4       62             41.354             41.5

我一直在想如何编写这个小算法,但事实是我甚至不知道如何开始。我需要一些专家的帮助。。。

不确定是否需要实际显示完成的结果,但这应该提供正确的计算。

// Start with the raw product data (array of object - from database likely)
    var 
        products = [
            {
                product_id: 1,
                sells: 45
            },
            {
                product_id: 2,
                sells: 31
            },
            {
                product_id: 3,
                sells: 12
            },
            {
                product_id: 4,
                sells: 62
            }
        ]
    ;
    
    // ###############################################################
    
    window.Pricing = {
        
        total_sum: 100, // This represents the 100€
        sales : 0,
        
        init: function( products ) {     
            return this.calculate_final_price( products );
        },
           
        get_price_per_sale: function( products ) {
    
            for( x in products ) {
                this.sales += products[x].sells;        
            }
            
            return this.total_sum / this.sales;                
        },
        
        calculate_final_price: function( products ) {
            var price_per_sale = this.get_price_per_sale( products );
            
            for( x in products ) {
                products[x].raw_price_next_week = +( products[x].sells * price_per_sale );
                products[x].final_price = +( Math.round( products[x].raw_price_next_week * 2 ) / 2 ).toFixed(1);        
            }
            
            return products;
        }
        
    };
    
    // ###############################################################
    
    // Init the pricing calculations and get the final objects with updated pricing.
    Pricing.init( products );

Fiddle here:http://jsfiddle.net/0nbbojp9/1/

好的,下面是我在javascript中得到的内容,正如您所要求的那样。你也可以在这里测试一下。

// 1.) Set array for product prices... I just put a random number of products
var productPrices = [10,20,20,30,30,30,25,10];
// 2.) Get initial total price to calculate price change
var productPriceSum = 0;
for (var i = 0; i < productPrices.length; i++) {
    productPriceSum += productPrices[i];
}
var priceChange = (100/productPriceSum);
// 3.) Change prices rounding to the nearest .5
productPriceSum = 0;
for (var i = 0; i < productPrices.length; i++) {
    var newPrice = Math.round((productPrices[i]*priceChange)*10)/10
    var npDecimal = (newPrice - Math.floor(newPrice))
    if(npDecimal < 0.5){
        newPrice = Math.floor(newPrice)
    }else{
        newPrice = Math.floor(newPrice) + .5
    }
    productPrices[i] = newPrice;
    productPriceSum += newPrice;
}
// 4.) Account for any missing or excess of numbers to get the total back to 100
var makeEvenHundred = (100 - productPriceSum)
for(var i = 0; i < (makeEvenHundred*2); i ++){
    if(makeEvenHundred < 0){
        productPrices[i] -= .5
    }else{
        productPrices[i] += .5
    }
}
// Proof it all worked!
productPriceSum = 0;
for (var i = 0; i < productPrices.length; i++) {
    alert('Product # ' + (i+1) + ' Price: ' + productPrices[i]);
    productPriceSum += productPrices[i];
}
alert('Total: ' + productPriceSum);

还要注意的是,第4节可能需要进行调整,但您希望逻辑在那里工作。按照我把它放在一起的方式,它会添加或删除第一个价格的值,直到总数回到100。此外,它还假设实际上有足够的产品可以一次添加或删除.5(你说的是20,所以我认为这会起作用)。

所以,如果这个网站有任何成功,只要知道我为你做了所有的工作;)

解决方案

诀窍是把问题分解成小块,然后分别处理。以下是分类:

  1. 将值向下四舍五入到最接近的整数
  2. 捕获十进制值
  3. 将十进制值除以以查看该值由多少个0.5组成
  4. 将数值0.5的倍数相乘,得到最接近的0.5值
  5. 对1中的值求和。值为4

您也可以调整closest变量以四舍五入到不同的值。

以下是这方面的实施情况。可以使用map函数对数据数组中的所有值执行normalization。在您的情况下,这将是一些ajax调用的结果。

实施

var data = [30.015, 20.677, 8.004, 41.354];
function normalize(value) {
  var closest = 0.5;
  var significand = Math.floor(value);
  var mantissa = (value % 1).toFixed(2);
  var normalized = Math.round(mantissa / closest) * closest;
  return significand + normalized;
}
var normalized = data.map(normalize);
console.log(normalized);
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>

资源

  • 数组映射函数