Home > Software design >  Does a while loop see updates to the variable it is checking upon running the code in the while loop
Does a while loop see updates to the variable it is checking upon running the code in the while loop

Time:10-08

I am trying to write an evaluate function for a JavaScript calculator function I am working on which is resulting in an infinite loop.

As the user uses the calculator and presses numbers and operators, it goes into an array called calculatorArray which looks like this: [586, "/", 2, "*", 5, " ", 17, "-", 12]

I wrote an evaluateArray function that has an array of objects called operations that is in BEDMAS order. Below that, I run operations.forEach which is meant to iterate over the operations object and run a while loop which checks if calculatorArray includes the operator, and if yes, it calls the function from the operator object and proceeds to use calculatorArray.splice(index - 1, 3, result); to remove the operator, and the preceding and subsequent value from the array, then replaces it with the result of the function.

My full code for the function is:

const evaluateArray = function() {
    
    operations = [
        {
            "operator": "/",
            "function": divide
        },{
            "operator": "x",
            "function": multiply
        },{
            "operator": " ",
            "function": add
        },{
            "operator": "-",
            "function": subtract
        }
    ]

    operations.forEach(function(operation) {
        while (calculatorArray.includes(operation.operator)) {
            const length = calculatorArray.length;
            const index = calculatorArray.indexOf(operation.operator);
            const num1 = calculatorArray.at(index-1);
            const num2 = calculatorArray.at(index 1);
            if (num2 <= length - 1) {
                result = operation.function(num1, num2);
                calculatorArray.splice(index - 1, 3, result);
            }
        }
    })
    updateDisplay();
}

From my understanding, the while (calculatorArray.includes(operation.operator)) is causing an infinite loop that causes my browser to completely freeze, but I don't understand why. I thought that the while loop would run splice to remove the said operator (lets say "/") from the array and after a certain number of iterations in the while loop, all of these would be gone completing the while loop. Then the forEach would do the same with the following operators until there are none left. Is it possible that the while loop is running against the prime array before the splice replaces the operator and preceding/subsequent number with the result of the operation function?

Does anybody have an idea what is causing the code to freeze my browser and the evaluation to fail?

CodePudding user response:

As noted in my comment, there seems to be some unusual logic where you compare the value of the second number to the length of the calculatorArray length (minus 1). In certain cases, the value of the second number is greater than the length of calculatorArray, meaning that if statement evaluates to false and the operator is never removed (which would likely cause an infinite loop).

Another unusual thing is in your operations array, you are checking for the operator x, but you are using the operator * in your calculatorArray. This wouldn't cause the infinite loop, but would cause multiplication to never happen.

You actually shouldn't need an if statement at all. Your code is set up to find all instances of an operator and perform the mathematical operation for that, then replace it with the result. Once all operators have been removed (thus all calculations should have been performed), the loop exits and you should have an array with 1 value (the result/answer).

let calculatorArray = [586, "/", 2, "*", 5, " ", 17, "-", 12];

const divide = (n1, n2) => n1/n2;
const multiply = (n1, n2) => n1*n2;
const add = (n1, n2) => n1 n2;
const subtract = (n1, n2) => n1-n2;

const evaluateArray = () => {
  const operations = [
    { "operator": "/", "function": divide },
    { "operator": "*", "function": multiply },
    { "operator": " ", "function": add },
    { "operator": "-", "function": subtract }
  ]
  
  operations.forEach(operation => {
    while(calculatorArray.includes(operation.operator)) {
      const length = calculatorArray.length;
      const index = calculatorArray.indexOf(operation.operator);
      const num1 = calculatorArray.at(index-1);
      const num2 = calculatorArray.at(index 1);
      
      result = operation.function(num1, num2);
      calculatorArray.splice(index - 1, 3, result);
    }
  })
  console.log(`result: ${calculatorArray}`);
}
evaluateArray();

  • Related