0

How to make this kind of function work? If I call it like calculate(2, 4, '*') it will return me a String '2*4'. I also tried parseInt with no success, it only makes first appear in String to Number.

function calculate(x, y, operation) {
  this.number = x + operation + y;
  return this.number;
}
Erick Petrucelli
  • 14,386
  • 8
  • 64
  • 84
ttmcswg
  • 67
  • 1
  • 8

4 Answers4

4

Just make an object with the wanted operators, test if the operator exist, and use it.

var operators = {
        '+': function (a, b) { return a + b; },
        '-': function (a, b) { return a - b; },
        '*': function (a, b) { return a * b; },
        '/': function (a, b) { return a / b; }
    },
    calculate = function (val1, val2, sign) {
        if (sign in operators) {
            return operators[sign](val1, val2);
        }
    }

console.log(calculate(6, 7, '*'));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • This key-value map with an Object is a interesting approach, but I believe it may become a lot of code for little functionality. I believe with ES2015+ arrow functions it would become even more concise and interesting. – Erick Petrucelli Aug 18 '17 at 19:06
1

This is a basic calculator, you already wrote all the code. just missing the eval.

Note: please note that for a simple calculator, the eval can be used. Provided you don't implement this in some critical project, etc, for security reasons, but if its for some internal use or for an assignment its not that bad and quite handy.

function calculator(x,y,operation){
  this.number=x+operation+y;
  return eval(this.number);
}
console.log(calculator(1,2,"+"));
console.log(calculator(1,2,"-"));
console.log(calculator(1,2,"*"));
console.log(calculator(1,2,"/"));
Naren Murali
  • 19,250
  • 3
  • 27
  • 54
1

Your operation argument is just a String, not a real operator. This is why it doesn't works as you'd like. So, you have some alternatives.

Using Eval

You could use the eval function to dinamically run a String as a piece of code, this way:

function calculate(x, y, operation) {
  return eval(x + operation + y)
}

While it seems so consise and clear, keep in mind that it's commonly a bad practice, for security, manutenibility and performance reasons (more about it here).


Using Conditionals

Sometimes the simplest idea is the best option: just use some conditionals.

function calculate(x, y, operation) {
  if (operation === '+') return x + y
  else if (operation === '-') return x - y
  else if (operation === '*') return x * y
  else if (operation === '/') return x / y
  else if (operation === '%') return x % y
  else if (operation === '**') return x ** y
  else return NaN
}

It may seems a little repetitive, but keep in mind that you don't have a lot of arithmetic operations to handle. In fact, all the binary arithmetic operators are handled above.

An alternative syntax wold be a switch case statement, but it's just a more verbose conditional structure, the ideia remains the same.


Using an Object with Functions

Another approach, strongly inspired by Nina Scholz' answer, is mapping String representations of operators with they equivalent function, with the help of an Object:

function calculate(x, y, operation) {
  var operators = {
    '+': function (a, b) { return a + b },
    '-': function (a, b) { return a - b },
    '*': function (a, b) { return a * b },
    '/': function (a, b) { return a / b },
    '%': function (a, b) { return a % b },
    '**': function (a, b) { return a ** b }
  }

  return operation in operators ? operators[operation](x, y) : NaN
}

If on an ES2015+ environment (see the compatibility), arrow functions can make it very elegant:

function calculate(x, y, operation) {
  const operators = {
    '+': (a, b) => a + b,
    '-': (a, b) => a - b,
    '*': (a, b) => a * b,
    '/': (a, b) => a / b,
    '%': (a, b) => a % b,
    '**': (a, b) => a ** b
  }

  return operation in operators ? operators[operation](x, y) : NaN
}

While I personally still believe that the simple conditional statements are enough for this case, this Object approach is very interesting to show a little about the JavaScript's flexibility.

Erick Petrucelli
  • 14,386
  • 8
  • 64
  • 84
0

You should divide it to 4 different cases:

calculate: function(x,y,operation){
      switch(operation){
         case "*":
           this.number = x*y;
           break;
         case "/":
           this.number=x/y;
           break;
         case "+":
           this.number= x+y;
           break;
         case "-":
           this.number= x-y;
           break;
         default:
            break;
      }

        return this.number;
}

it's also very easy to scale it...

GuyL
  • 36
  • 2