javascript - 如何在 Javascript 中将一个数组值递增到另一个数组值?

标签 javascript

//value of currency denominations
    var currencyTable = [100, 20, 10, 5, 1, 0.25, 0.1, 0.05, 0.01];

//total cash at each currencyTable denomination in the cash register 
    var cashInDrawer = [100, 60, 20, 55, 90, 4.25, 3.1, 2.05, 1.01];

//total change due
    var changeDue = 96.74;

我的目标是从最大面额的现金到最小面额的可用现金中返回正确的零钱。

我不知道如何在 changeDue>= 时将 currencyTable 中的值增加到 cashInDrawer 中的可用金额>currencyTable[i].

到目前为止我已经做到了:

var total = [];
  for (let i = 0; i < currencyTable.length; i++){
  while (changeDue >= currencyTable[i]){
    total.push(currencyTable[i])
    changeDue-=currencyTable[i];
  }
 }return total;

但这只会返回:

[20, 20, 20, 20, 10, 5, 1, 0.25, 0.25, 0.1, 0.1, 0.01, 0.01, 0.01]

我想返回的地方:

[60, 20, 15, 1, 0.5, 0.2, 0.04]

在循环的某个地方,我意识到 changeDue 正在被更改为重复小数,但我发现了一个使用 .toFixed() 的临时解决方法。

最佳答案

您完全走在正确的道路上。但是,不是每次都在内循环中调用 push,而是需要添加循环时上次推送的数量。可能最简单的方法是添加一个变量,然后在最后推送。您还必须检查 cashInDrawer 并在添加到“total”时减少 cashInDrawer

其中存在一个固有问题:您正在使用 JavaScript 的数字类型来处理金钱。但是 JavaScript 的数字类型不适合处理货币,IEEE-754 二进制浮点值在十进制领域有臭名昭著的不精确问题,例如著名的:

console.log(0.1 + 0.2); // 0.30000000000000004

这就是这个问题。如果我们只是应用上面的逻辑修复,我们会得到(参见 *** 行):

//value of currency denominations
var currencyTable = [100, 20, 10, 5, 1, 0.25, 0.1, 0.05, 0.01];

//total cash at each currencyTable denomination in the cash register 
var cashInDrawer = [100, 60, 20, 55, 90, 4.25, 3.1, 2.05, 1.01];

//total change due
var changeDue = 96.74;

var total = [];
for (let i = 0; i < currencyTable.length; i++){
    let amount = 0;                                                 // ***
    while (changeDue >= currencyTable[i] && cashInDrawer[i] > 0) {  // ***
        amount += currencyTable[i];                                 // ***
        changeDue -= currencyTable[i];
        cashInDrawer[i] -= currencyTable[i];                        // ***
    }
    // I assume you want to push the amount even if it's 0
    total.push(amount);                                             // ***
}
//return total;
console.log(total);

请注意,最后一个条目是 0.03,而不是 0.04。这是因为 changeDue 随着我们的进行变得越来越不精确,如果我们记录它,我们可以看到:

//value of currency denominations
var currencyTable = [100, 20, 10, 5, 1, 0.25, 0.1, 0.05, 0.01];

//total cash at each currencyTable denomination in the cash register 
var cashInDrawer = [100, 60, 20, 55, 90, 4.25, 3.1, 2.05, 1.01];

//total change due
var changeDue = 96.74;

var total = [];
for (let i = 0; i < currencyTable.length; i++){
    let amount = 0;                                                 // ***
    while (changeDue >= currencyTable[i] && cashInDrawer[i] > 0) {  // ***
        amount += currencyTable[i];                                 // ***
        changeDue -= currencyTable[i];
        cashInDrawer[i] -= currencyTable[i];                        // ***
        console.log(changeDue);
    }
    // I assume you want to push the amount even if it's 0
    total.push(amount);                                             // ***
}
//return total;
console.log(total);

最后,0.009999999999994869 不是 >= 0.1 因此循环提前结束。

参见 this question's answers了解解决该问题的各种方法。

一种常见的解决方案是使用数字 * 100 并保持四舍五入。 (有时您可能会使用 * 10000 然后四舍五入到小数点后两位,等等)这是一般的想法,必要时进行调整:

//value of currency denominations
var currencyTable = [100, 20, 10, 5, 1, 0.25, 0.1, 0.05, 0.01];
currencyTable = currencyTable.map(entry => Math.round(entry * 100));   // ***

//total cash at each currencyTable denomination in the cash register 
var cashInDrawer = [100, 60, 20, 55, 90, 4.25, 3.1, 2.05, 1.01];
cashInDrawer = cashInDrawer.map(entry => Math.round(entry * 100));     // ***

//total change due
var changeDue = 96.74;

changeDue = Math.round(changeDue * 100);                                // ***
var total = [];
for (let i = 0; i < currencyTable.length; i++){
    let amount = 0;
    while (changeDue >= currencyTable[i] && cashInDrawer[i] > 0) {
        amount += currencyTable[i];
        changeDue -= currencyTable[i];
        cashInDrawer[i] -= currencyTable[i];
    }
    // I assume you want to push the amount even if it's 0
    total.push(amount);
}
//return total;
for (const entry of total) {
    console.log(entry / 100);
}

关于javascript - 如何在 Javascript 中将一个数组值递增到另一个数组值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53681042/

相关文章:

javascript - jsPDF-AutoTable 中的 Rowspan 问题

javascript - 我如何在同一个函数中通过 id 获得 2 个类

javascript - 如何使 bootstrap popover 多次打开和关闭?

javascript - HTML 控件功能

javascript - HTML 中的脚本解析顺序

JavaScript : RemoveEventListener with Anonym Function

javascript - 防止浏览器缓存某些 JavaScript 文件

javascript - 运行函数后更改 Google map 标记 HTML

javascript - 导入到 Electron JS 时网站不起作用

javascript - 按下 Enter 后,Jquery UI 自动完成功能不会提交