How to code calculator in javascript without eval

So, I searched high and low, and I can not find the answer to this question. I tried to do this about three times and got a basic key, basically storing the input to the array as a string, parsing numbers, then turning on the operator to evaluate integers, but I have really hard to determine the logic of the chain. Anyone have any suggestions? Maybe even just psuedocode? I really don't want to use eval. Many thanks

+4
source share
1 answer

For a simple calculator with 5 operators (^, *, /, +, -) and without parentheses, you can do something like this. First, it’s convenient to turn a string into an array of numbers and operators. Then we go through the array, looking for each operator in order of priority, and apply the operator to the numbers preceding and following it.

function parseCalculationString(s) {
    // --- Parse a calculation string into an array of numbers and operators
    var calculation = [],
        current = '';
    for (var i = 0, ch; ch = s.charAt(i); i++) {
        if ('^*/+-'.indexOf(ch) > -1) {
            if (current == '' && ch == '-') {
                current = '-';
            } else {
                calculation.push(parseFloat(current), ch);
                current = '';
            }
        } else {
            current += s.charAt(i);
        }
    }
    if (current != '') {
        calculation.push(parseFloat(current));
    }
    return calculation;
}

function calculate(calc) {
    // --- Perform a calculation expressed as an array of operators and numbers
    var ops = [{'^': (a, b) => Math.pow(a, b)},
               {'*': (a, b) => a * b, '/': (a, b) => a / b},
               {'+': (a, b) => a + b, '-': (a, b) => a - b}],
        newCalc = [],
        currentOp;
    for (var i = 0; i < ops.length; i++) {
        for (var j = 0; j < calc.length; j++) {
            if (ops[i][calc[j]]) {
                currentOp = ops[i][calc[j]];
            } else if (currentOp) {
                newCalc[newCalc.length - 1] = 
                    currentOp(newCalc[newCalc.length - 1], calc[j]);
                currentOp = null;
            } else {
                newCalc.push(calc[j]);
            }
            console.log(newCalc);
        }
        calc = newCalc;
        newCalc = [];
    }
    if (calc.length > 1) {
        console.log('Error: unable to resolve calculation');
        return calc;
    } else {
        return calc[0];
    }
}
var calculateButton = document.getElementById('calculate'),
    userInput = document.getElementById('userInput'),
    result = document.getElementById('result');
calculateButton.addEventListener('click', function() {
    result.innerHTML = "The answer is " + calculate(parseCalculationString(userInput.value));
});
<input type="text" id="userInput" />
<input type="button" value="Calculate" id="calculate" />
<div id="result"></div>
Run codeHide result

( jsfiddle ). To enable parentheses, you can tell the function calculateto check the brackets before it starts looking for any of the other operators, and then recursively call itself in the expression in each set of parentheses. The parsing function can also be improved, for example. removal of any gap and elimination of errors.

+7
source

All Articles