Reputation: 628
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
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.
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
Upvotes: 1
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 } )
}
Upvotes: 1
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
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
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
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