Estoy tratando de construir una calculadora con Javscript y he implementado todos los operadores comunes. Ahora me gustaría implementar un operador factorial (!).
Tengo una función factorial(n) definida, ahora me gustaría reemplazar el ! con mi función y luego use eval() en la cadena resultante y muestre la salida. Puedo implementarlo iterando hacia atrás, pero no funciona con corchetes.
Aquí está mi código -
function replaceFactorial(expression) { expression = expression.replace(' ', ''); index = expression.indexOf('!'); number = ''; for (let i = index - 1; i >= 0; --i) { if (!(['+', '-', '*', '/'].includes(expression.charAt(i)))) { number += expression.charAt(i); } else { break; } } console.log(number + '!', 'factorial(' + number + ')') expression = expression.replace(number + '!', 'factorial(' + number + ')'); return eval(expression); } Por ejemplo:
factorial('5! + 5') genera 125 . Como era de esperar, pero
factorial('(2 + 3)!') no funciona!
En mi método, compruebo hacia atrás desde ! y una vez que llegue a un operador, pare y cambie el número. Pero no funciona cuando tengo brackets.
¿Cómo puedo hacer que funcione?
Otra idea es definir factorial como un método prototipo de Number . El reemplazo se vuelve entonces bastante trivial: cada "!" se puede reemplazar con ["factorial"]() :
"use strict"; // To avoid this-wrapping overhead (optional) Number.prototype.factorial = function () { return this > 0 ? this * (this-1).factorial() : 1; } function evaluate(str) { str = str.replaceAll("!", '["factorial"]()'); console.log(str); // Just to see what it generates return eval(str); } console.log(evaluate("1 + (2*3)!")); // 721 console.log(evaluate("3!!-1")); // 619 console.log(evaluate("(2-2)!*3")); // 3 console.log(evaluate("'abc'.length!")); // 6Podría usar una expresión regular que busca dígitos y un golpe siguiente, ambos agrupados. Luego tome una función para llamar factorial con el segundo argumento.
function factorial(n) { return +!n || n * factorial(n - 1); } const string = '5! + 2!' console.log(string.replace(/(\d+)(!)/g, (_, v) => factorial(v)));