1

Apologies if my question is unclear, wasn't sure how to word it!

I'm trying to create a function that takes two numbers and a string which contains an operator (e.g. '+', '-', '*', '/').

I've used .valueOf() on the string to extract the operator, however the num1 and num2 arguments do not seem to evaluate to the passed number parameters. Why is this happening?

function calculate(num1, operator, num2) {
  return `num1 ${operator.valueOf()} num2`;
}
undefined


calculate(2, '+', 1);
"num1 + num2"         //result
Lauren
  • 109
  • 2
  • 11
  • You cannot do what you're trying to do without using `eval()` or `new Function()`, unless you directly examine the operator parameter and programmatically act on it as appropriate. – Pointy Aug 29 '18 at 21:39
  • @Pointy ...but eval() is not an evil..... I believe a switch can do the work. – gaetanoM Aug 29 '18 at 21:40
  • 2
    @gaetanoM and the switch would be what the second part of that comment is referring too. – epascarello Aug 29 '18 at 21:41

2 Answers2

2

If I understand your requirements, you could use eval() to achieve this:

function calculate(num1, operator, num2) {
  return eval(`${num1} ${operator} ${num2}`);
}

console.log(calculate(2, '+', 1)); // 3

Alternatively, you could avoid the use of eval() by using a switch block, which would make your code easier to debug and potentially more secure:

function calculate(num1, operator, num2) {
  switch (operator.trim()) { // Trim possible white spaces to improve reliability
    case '+':
      return num1 + num2
    case '-':
      return num1 - num2
    case '/':
      return num1 / num2
    case '*':
      return num1 * num2
  }
}

console.log(calculate(2, '+', 1)); // 3
Dacre Denny
  • 29,664
  • 5
  • 45
  • 65
2

The best way to do what you want is with an object that maps operator names to functions.

const opmap = {
  "+": (x, y) => x + y,
  "-": (x, y) => x - y,
  "*": (x, y) => x * y,
  "/": (x, y) => x / y,
};

function calculate(num1, operator, num2) {
  if (operator in opmap) {
    return opmap[operator](num1, num2);
  }
}

console.log(calculate(2, '+', 1));
Barmar
  • 741,623
  • 53
  • 500
  • 612