Esta función, que se ejecutará cuando ingrese en el campo de entrada, calculará cuánto dinero tiene que devolver con el tipo x al cliente.
Pero obtengo un error de tamaño de pila en algún momento para 6 dígitos y cada vez para 7 dígitos.
Reproducir: poner 1234567 en el cuadro de entrada y comprobar la consola.
Función:
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'); } })
Zona de juegos: https://jsbin.com/kuwomalare/edit?html,js,console,output
Terminas teniendo demasiadas llamadas recursivas cuando el valor de entrada es grande. Debería ser bastante sencillo convertir de recursivo a iterativo usando un bucle while
. El único problema con el que me encontré fue que el punto flotante no bajaba a 0 (como se menciona en el comentario de @Keith ). Al hacer cálculos de dinero, generalmente es mejor usar números enteros. Utilice la denominación más pequeña de la moneda. Por ejemplo, en moneda estadounidense, serían centavos. Solo convierta a decimal (o dólares en este caso) cuando muestre los valores.
También he simplificado un poco tus cálculos. Debido a estos cambios, ahora podría usar la recursividad, si lo desea, ya que el nivel máximo de recursividad ahora es 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">