Skip to content

The approach for reducing the complexity of conditional statements

There is one project challenge on freecodecamp about building a calculator and I just managed to pass all the tests but when looking back on my code, the section dealing with the operations are barely readable. I’ve read some articles online regarding how to reduce the complexity of conditionals and the principles to keep in mind for more easy-to-understand logic.

However, figuring out the achievable logics for this task in javascript is quite challenging to me now. I was trying to meet two conditions with this section of code as follows:

User Story #13: If 2 or more operators are entered consecutively, the operation performed should be the last operator entered (excluding the negative (-) sign). For example, if 5 + * 7 = is entered, the result should be 35 (i.e. 5 * 7); if 5 * – 5 = is entered, the result should be -25 (i.e. 5 * (-5)).

User Story #14: Pressing an operator immediately following = should start a new calculation that operates on the result of the previous evaluation.

Here is the link to the page for this particular challenge and this is the link to the code I wrote by far.

Is there any tips and advice on refining the code or other approaches for coping with this part?

handleOperation(event){
    const {value}=event.target
    const displayLength=this.state.display.length
    const condition1=this.state.display=="+"||this.state.display=="-"||this.state.display=="×"||this.state.display=="÷"||this.state.display==""
    const condition2=/^d*.?d*$/.test(this.state.input)&&!/=/.test(this.state.display)
    const condition3=this.state.input=="-"&&(this.state.display.charAt(displayLength-2)=="+"||this.state.display.charAt(displayLength-2)=="-"||this.state.display.charAt(displayLength-2)=="×"||this.state.display.charAt(displayLength-2)=="÷")
    const condition4=this.state.input=="-"&&value=="-"&&!/=/.test(this.state.display)
    const condition5=this.state.input=="-"&&value!=="-"&&!/=/.test(this.state.display)
    const condition6=this.state.input!=="-"&&value!=="-"&&!/=/.test(this.state.display)
    const condition7=this.state.input!=="-"&&value=="-"&&!/=/.test(this.state.display) 
    const condition8=/=/.test(this.state.display)
    console.log(this.state.display.replace(/=/,"$'"))
    if(condition1){
      this.setState({
      input:value,
      display:value
    })
    }else if(condition2){
      this.setState({
        input:value,
        display:this.state.display+value
      })
    }else if(condition3){
      this.setState({
        input:value,
        display:this.state.display.replace(/[+-×÷]-$/,value)
      })     
    }
    else if(condition4){
      this.setState({
        input:value,
        display:this.state.display.replace(/(?<=d)-$/,"--")
      })
    }else if(condition5){
      this.setState({
        input:value,
        display:this.state.display.replace(/(?<=d)-/,value)
      })
    }else if(condition6){
      this.setState({
        input:value,
        display:this.state.display.substring(0,displayLength-1)+value
      })
    }else if(condition7){
      this.setState({
        input:value,
        display:this.state.display+value
      })
    } else if(condition8){
      this.setState({
        input:value,
        display:this.state.display.substring(this.state.display.indexOf("=")+1)+value
      })
    }  
  }

Answer

Break down the process to the basic steps:

  • get the operation(s) from the string
  • get the numbers from the string
  • do the operation

Here’s a snippet for this:

const calcs = [
  "5 + 15",
  "5 - 5",
  "5 - - 5",
  "5 / + 5",
  "5 / - 5",
  "5 / * + 5",
  "5 / + * 5",
]

const container = document.getElementById("container");

// getting the operation(s) from the string
const getOperation = (calc) => {
  const regex = /d*([+|-|*|/]+)d*/g
  const listOfOperations = calc.match(regex)
  let operation = listOfOperations.pop()
  let nextIsNegative = false
  // if the operation is "-" and it wasn't the last item
  if (listOfOperations.length && operation === "-") {
    operation = listOfOperations.pop()
    nextIsNegative = true
  }
  return {
    operation,
    nextIsNegative,
  }
}

// getting the numbers from the string
const getNumbers = (calc) => {
  const regex = /d+/g
  return calc.match(regex)
}


// doing the calculation
const doOperation = ({
  operation,
  nextIsNegative
}, [num1, num2]) => {
  const operationObj = {
    "+": (a, b) => a + b,
    "-": (a, b) => a - b,
    "*": (a, b) => a * b,
    "/": (a, b) => a / b,
  }
  const n1 = Number(num1)
  const n2 = nextIsNegative ? Number(num2) * -1 : Number(num2)
  return operationObj[operation](n1, n2)
}

(function(calcs) {
  const html = calcs.map((calc, i) => {
    const operation = getOperation(calc)
    const numbers = getNumbers(calc)
    const result = doOperation(operation, numbers)
    return `
      <div id="in${i}">${calc}</div>
      <div id="operation${i}">${JSON.stringify(operation)}</div>
      <div id="result${i}">${ result }</div>`
  })
  container.innerHTML = html.join('')
})(calcs);
#container {
  display: grid;
  grid-template-columns: 80px 1fr 80px;
}
<div id="container"></div>