javascript - How do I increment an array value up to another array value in 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;
My goal is to return the correct change from the cash available from the greatest cash denomination to the lowest.
I can't figure out how to increment a value in currencyTable up to the available amount in cashInDrawer while changeDue >= currencyTable[i].
I've managed so far:
var total = [];
for (let i = 0; i < currencyTable.length; i++){
while (changeDue >= currencyTable[i]){
total.push(currencyTable[i])
changeDue-=currencyTable[i];
}
}return total;
but this only returns:
[20, 20, 20, 20, 10, 5, 1, 0.25, 0.25, 0.1, 0.1, 0.01, 0.01, 0.01]
where I want to return:
[60, 20, 15, 1, 0.5, 0.2, 0.04]
Somewhere in the loop I realize changeDue is being changed into a repeating decimal but I found a temporary workaround using .toFixed().
解决方案
你完全在正确的道路上。但是,不是push
每次都在内部循环中调用,而是需要在循环时添加上一次推送的数量。可能最简单的方法是添加一个变量,然后在最后推送。当您添加到`total cashInDrawer
.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
,所以循环提前结束。
有关解决此问题的各种方法,请参阅此问题的答案。
一种常见的解决方案是使用数字* 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);
}
推荐阅读
- node.js - 使用 papaparse 忽略 csv 文件的标题
- sql - 在同一个表中分组和连接行 - SQLite
- python - 在我将其更改为“agg”之前,我的后端是什么?
- python - 为什么我的 tkinter 标签会出现“未知选项“-Text””?
- python - 两个 Asyncio 同时休眠
- assembly - 如何比较输入数字和汇编中的数字?
- batch-file - 如何仅移动与另一个文件夹中的文件名匹配的文件
- c - 如何在 C 中定义一个接受格式化输入字符串的函数?
- java - 在springboot应用程序中登录h2 db时如何超越登录屏幕
- ios - 带有 CloudKit 的 CoreData:记录类型未显示在仪表板中