Alistair Chisholm
Alistair Chisholm

Reputation: 628

Building a calculator object

While trying to learn some fundamental JS, I'm building a Calculator object that should add/subtract/divide/multiply methods that accept any number of arguments. Here's where I'm at:

var Calculator = {}; //

Calculator.add = function () {
    var addValue = 0;
    for (var i = 0; i < arguments.length; i++) {
        addValue = addValue + arguments[i];
    }
    return addValue;
}
Calculator.subtract = function () {
    var subtractValue = 0;
    for (var i = 0; i < arguments.length; i++) {
        subtractValue = subtractValue - arguments[i];
    }
    return subtractValue;
}

console.log(Calculator.add(1,4));
console.log(Calculator.subtract(2,4)); // outputs -6. Should output -2. (2,4,6) should give -8 etc.

The add method works, so I moved onto the subtract and quickly realised that this tactic is not going to work for the rest of my methods. There is no doubt, a much smarter way to pull this off. Looking forward to your advice.

Thank you.

Upvotes: 0

Views: 239

Answers (6)

Andy
Andy

Reputation: 63587

What you could do is specify the first number in the argument list as the main number you want to subtract from, and then loop over the other arguments subtracting them from the first argument:

Calculator.subtract = function () {
  var first = arguments[0];
  for (var i = 1, l = arguments.length; i < l; i++) {
    first -= arguments[i];
  }
  return first;
}

Calculator.subtract(12, 2, 4)); // outputs 6.

Fiddle

Alternatively, perhaps you'd like to have a running total in your object instead and use some nice chaining to process the submitted numbers:

var Calculator = {

  total: 0,

  add: function () {
    for (var i = 0; i < arguments.length; i++) {
      this.total += arguments[i];
    }
    return this;
  },

  subtract: function () {
    for (var i = 0; i < arguments.length; i++) {
      this.total -= arguments[i];
    }
    return this;
  },

  display: function () {
    console.log(this.total);
    return this;
  }

};

Calculator.add(1, 4).display(); // 5
Calculator.subtract(2, 1).display(); // 2

Or even:

Calculator.add(1, 4).subtract(2, 1).display();  // 2

Fiddle

Upvotes: 1

pawel
pawel

Reputation: 36995

I'd assume it's a learning exercise and you'd like to learn some language features along the way.

You can look at subtraction as addition with the sign inverted, as in 2-4 = 2 + (-4). You have addition logic worked out, so you can use it in you subtraction function:

Calculator.subtract = function () {
    // the first number stays the same, multiplying by 1 is short for parseInt.
    var subtractValue = 1 * arguments[0]; 

    // convert the rest of arguments to an array
    var numbers = [].slice.call( arguments, 1 ); 

    // invert the sign of the numbers by multiplying them * -1
    numbers = numbers.map( function(n){ return -1*n; } );

    // and apply the addition to these arguments...
    var sum = this.add.apply( this, numbers );

    // add the sum to the first number and return the result
    subtractValue += sum;
    return subtractValue;
}

Less verbose version

Calculator.subtract = function () {
    var subtractValue = 1 * arguments[0];
    var numbers = [].slice.call( arguments, 1 );
    subtractValue += this.add.apply( this, numbers.map( function(n){ return -1*n; } ));
    return subtractValue;
}

In the future you may wish to refactor addition to use, for example, the reduce method of an array. By re-using addition you avoid the need to rewrite two for loops in different places. Just update the addition and subtraction still works unchanged.

Calculator.add = function () {
    var numbers = [].slice.call( arguments );
    return numbers.reduce( function(num, prev){ return prev + num } )
}

http://jsfiddle.net/6Ss7r/1/

Upvotes: 1

Amit Joki
Amit Joki

Reputation: 59292

Sorry! I misunderstood your question but now it works.

Just use this:

var Calculator = {}; //

Calculator.add = function () {
    var returnVal = 0;
    for (var i = 0; i < arguments.length; i++) {
        returnVal += arguments[i];
    }
    return returnVal;
};
Calculator.subtract = function () {
    var returnVal = arguments[0];
    for (var i = 0; i < arguments.length - 1; i++) {
        returnVal -= arguments[i + 1];
    }
    return returnVal;
};
alert(Calculator.add(1, 4, 5));
alert(Calculator.subtract(2, 4, 6)); // outputs -6.

Demo: http://jsfiddle.net/8fN5W/1/

Upvotes: 1

Rajdeep Siddhapura
Rajdeep Siddhapura

Reputation: 933

This is probably a better alternative. It subtracts every other argument from first argument

    var subtractValue = arguments[0];  // add try catch in case no arguments are passed
    for (var i = 1; i < arguments.length; i++) {
        subtractValue = subtractValue - arguments[i];
    }
    return subtractValue;

OUTPUTS:

console.log(Calculator.subtract(2,4)); // outputs -2
console.log(Calculator.subtract(6,4,1)); // outputs 1
console.log(Calculator.subtract(10,1,1,1,1,1,1,1)); // outputs 3

Upvotes: 0

Deepu--Java
Deepu--Java

Reputation: 3840

Calculator.add = function () {
    var addValue = 0;
    for (var i = 0; i < arguments.length; i++) {
        addValue = addValue + arguments[i];
    }
    return addValue;
}
Calculator.subtract = function () {
    var subtractValue = arguments[0];
    for (var i = 1; i < arguments.length; i++) {
        subtractValue = subtractValue - arguments[i];
    }
    return subtractValue;
}

Upvotes: 1

Jonas Grumann
Jonas Grumann

Reputation: 10786

Substract to what? What is the beginning number? The first element in the arguments? in that case:

var subtractValue = arguments[0];
for (var i = 1; i < arguments.length; i++) {
    subtractValue = subtractValue - arguments[i];
}

Also, I suggest you save the arguments.length in a variable:

for(var i = 1, l = arguments.length; i < l ; i ++)

That way you don't have to read the length of the array every loop. This doesn't affect performance in your case but with bigger arrays it might do.

Upvotes: 2

Related Questions