Recursive Function Uncaught RangeError: Maximum call stack size exceeded
Recursive Function Uncaught RangeError: Maximum call stack size exceeded
此函数将在您输入输入字段时执行,然后它将计算您需要 return 给客户多少钱 return。
但是有时 6 位和每次 7 位都会出现堆栈大小错误。
重现:输入框输入1234567,查看控制台
函数:
let returnList = [];
let predictorList = [
100, 50, 20, 10, 5, 1, 0.5, 0.25, 0.1, 0.05, 0.01,
];
let total = 11.23
function isRemainingMoney(value) {
let remainingValue = value;
// when remaning value becomes zero then return the returnlist
if (remainingValue == 0) {
return returnList;
}
for (let pRed of predictorList) {
/* remainingValue is greater than predictor value then push it
eg: 41.33 > 20
21.33 > 20
1.33 > 1
0.33 > 0.25
0.08 > 0.05
0.03 > 0.01 * 3 times
*/
if (remainingValue >= pRed) {
const isPredExist = returnList.find(
(pItem) => +pItem.money == +pRed
);
if (!!isPredExist) {
isPredExist.count += 1;
isPredExist.total = isPredExist.total + +pRed;
} else {
returnList.push({
type: pRed,
money: pRed,
count: 1,
total: pRed,
});
}
remainingValue = +remainingValue.toFixed(2) - pRed;
break;
}
}
// recursive call the same method untill remainivalue becomes zero.
return isRemainingMoney(+remainingValue.toFixed(2));
}
document.querySelector('input').addEventListener('change', (event) => {
if(!!event.target.value) {
returnList.length = 0;
returnList = isRemainingMoney(+event.target.value - total);
console.log(returnList, 'returnList');
}
})
游乐场:https://jsbin.com/kuwomalare/edit?html,js,console,output
当输入值很大时,您最终会进行过多的递归调用。它 应该 相当直接地使用 while
循环从递归转换为迭代。我 运行 遇到的唯一问题是浮点数没有下降到 0(如 中提到的)。在进行货币计算时,通常最好使用整数。使用最小面额的货币。例如,在美国货币中,这将是美分。显示值时仅转换为小数(或本例中的美元)。
我也稍微简化了你的计算。由于这些更改,如果你愿意,你现在实际上可以使用递归,因为现在递归的最大级别是 predictorList.length
.
let predictorList = [
10000, 5000, 2000, 1000, 500, 100, 50, 25, 10, 5, 1
];
let total = 709;
function isRemainingMoney(value) {
let returnList = [];
// when remaning value becomes zero then return the returnlist
while (value != 0) {
for (let pRed of predictorList) {
if (value >= pRed) {
returnList.push({
money: pRed / 100,
count: Math.floor(value / pRed),
});
value %= pRed;
}
}
}
return returnList;
}
document.querySelector('input').addEventListener('change', (event) => {
if (!!event.target.value) {
let returnList = isRemainingMoney(+event.target.value * 100 - total);
console.log(returnList, 'returnList');
}
})
<input type="number">
此函数将在您输入输入字段时执行,然后它将计算您需要 return 给客户多少钱 return。
但是有时 6 位和每次 7 位都会出现堆栈大小错误。
重现:输入框输入1234567,查看控制台
函数:
let returnList = [];
let predictorList = [
100, 50, 20, 10, 5, 1, 0.5, 0.25, 0.1, 0.05, 0.01,
];
let total = 11.23
function isRemainingMoney(value) {
let remainingValue = value;
// when remaning value becomes zero then return the returnlist
if (remainingValue == 0) {
return returnList;
}
for (let pRed of predictorList) {
/* remainingValue is greater than predictor value then push it
eg: 41.33 > 20
21.33 > 20
1.33 > 1
0.33 > 0.25
0.08 > 0.05
0.03 > 0.01 * 3 times
*/
if (remainingValue >= pRed) {
const isPredExist = returnList.find(
(pItem) => +pItem.money == +pRed
);
if (!!isPredExist) {
isPredExist.count += 1;
isPredExist.total = isPredExist.total + +pRed;
} else {
returnList.push({
type: pRed,
money: pRed,
count: 1,
total: pRed,
});
}
remainingValue = +remainingValue.toFixed(2) - pRed;
break;
}
}
// recursive call the same method untill remainivalue becomes zero.
return isRemainingMoney(+remainingValue.toFixed(2));
}
document.querySelector('input').addEventListener('change', (event) => {
if(!!event.target.value) {
returnList.length = 0;
returnList = isRemainingMoney(+event.target.value - total);
console.log(returnList, 'returnList');
}
})
游乐场:https://jsbin.com/kuwomalare/edit?html,js,console,output
当输入值很大时,您最终会进行过多的递归调用。它 应该 相当直接地使用 while
循环从递归转换为迭代。我 运行 遇到的唯一问题是浮点数没有下降到 0(如
我也稍微简化了你的计算。由于这些更改,如果你愿意,你现在实际上可以使用递归,因为现在递归的最大级别是 predictorList.length
.
let predictorList = [
10000, 5000, 2000, 1000, 500, 100, 50, 25, 10, 5, 1
];
let total = 709;
function isRemainingMoney(value) {
let returnList = [];
// when remaning value becomes zero then return the returnlist
while (value != 0) {
for (let pRed of predictorList) {
if (value >= pRed) {
returnList.push({
money: pRed / 100,
count: Math.floor(value / pRed),
});
value %= pRed;
}
}
}
return returnList;
}
document.querySelector('input').addEventListener('change', (event) => {
if (!!event.target.value) {
let returnList = isRemainingMoney(+event.target.value * 100 - total);
console.log(returnList, 'returnList');
}
})
<input type="number">