Reputation: 101
I'm new to JavaScript, and are fooling around to really understand the basics. Now I try to make a calculator. A very basic one, that can add, subrtact, devide and multiply. I've gotten it to work with this code(showing multiply only:
var multiply = function () {
var numbers = prompt("How many numbers do you want to multiply?","At least 2, max 4");
numbers = Number(numbers);
switch (numbers){
case 2:
num1 = prompt("Your first number: ");
num2 = prompt("Your second number: ");
ans = Number(num1) * Number(num2);
alert(num1 + " * " + num2 + " = " + ans);
break;
case 3:
num1 = Number(prompt("Your first number: "));
num2 = Number(prompt("Your second number: "));
num3 = Number(prompt("Your third number: "));
ans = Number(num1) * Number(num2) * Number(num3);
alert(num1 + " * " + num2 + " * " + num3 + " = " + ans);
break;
case 4:
num1 = Number(prompt("Your first number: "));
num2 = Number(prompt("Your second number: "));
num3 = Number(prompt("Your third number: "));
num4 = Number(prompt("Your fourth number: "));
ans = Number(num1) * Number(num2) * Number(num3) * Number(num4);
alert(num1 + " * " + num2 + " * " + num3 + " * " + num4 + " = " + ans);
break;
default:
alert("Not valid");
break;
}
};
multiply();
My problem is that I'm very limited when it comes to how many numbers the user can multiply. Making a switch case for each possible quantity is going to take a while, so I thought of this:
var multiply = function () {
var numbers = [];
var ans = 0;
var times = prompt("How many numbers do you want to multiply?");
for(var i = 0; i<times; i++){
Number(numbers.push(prompt("Please, enter one of your numbers")));
}
alert(ans);
};
multiply();
So, my question is: How can I get "ans" to be equal to each element of my array "numbers" multiplied with eachother?
Upvotes: 0
Views: 6663
Reputation: 617
Reduce is probably the right answer, but to give you a more complete understanding of what it's actually doing, take a look at this. This is how I would manually do basically the same thing, adding a few guards to make it more safe.
//This is an enum. It's basically a cleaner and more
//scalable way to define constants. Here I'm using an
//integer to represent each of the four operations
var OPERATIONS = {
'ADD': 1,
'SUBTRACT': 2,
'MULTIPLY': 3,
'DIVIDE': 4
};
function calc (operation, values)
{
if (!operation || !values || values.length < 2)
{
//The inputs aren't valid, so throw some kind of error
}
//This will be used in all of our cases, so
//we define it at a larger scope
var result;
switch (operation)
{
case OPERATIONS.MULTIPLY:
//Extracts the first value and stores it
result = values.shift ();
//Iterate through the remaining values.
//Remember that the first value is no
//longer in the set
values.forEach (function (value, index)
{
//*= is a unary operator which multiplies a value by
//the operand, and then stores it back in itself.
//This is equivalent to result = result * value.
result *= value;
});
break;
//Create cases for ADD, SUBTRACT, and DIVIDE
}
return result;
}
//Test cases
console.log (calc (OPERATIONS.ADD, [1, 1]); //Prints 2
console.log (calc (OPERATIONS.SUBTRACT, [10, 1, 1]); //Prints 8
console.log (calc (OPERATIONS.MULTIPLY, [1, 2, 3, 4]); //Prints 24
console.log (calc (OPERATIONS.ADD, [calc (OPERATIONS.MULTIPLY, [5, 5], 3, 100]); //Prints 128
You can make it a bit more generalised if you want doing something like this...
function calc2 (operations, values)
{
//You need one more value than operation here
if (!operations || !values || values.length < 2 || (values.length - operations.length !== 1))
{
//The inputs aren't valid, so throw some kind of error
}
var result = values.shift ();
while (values.length)
{
switch (operations[0])
{
case OPERATIONS.ADD:
result += values[0]
break;
case OPERATIONS.SUBTRACT:
result -= values[0]
break;
case OPERATIONS.MULTIPLY:
result *= values[0]
break;
case OPERATIONS.DIVIDE:
result /= values[0]
break;
default:
//Something has gone horribly wrong. Thrown an error
}
//Work your way down the array by continually
//removing the first value
values.shift ();
operations.shift ();
}
//Note that this method solves the equation linerally;
//BEDMAS (or PEMDAS, depending on where you're from)
//is not honoured.
return result;
}
//Test cases
console.log (calc ([OPERATIONS.ADD], [1, 1])); //Prints 2
console.log (calc ([OPERATIONS.ADD, OPERATIONS.ADD], [1, 2, 3])); //Prints 6
console.log (calc ([OPERATIONS.ADD, OPERATIONS.ADD, OPERATIONS.DIVIDE], [6, 7, 5, 3])); //Prints 6
This second function would be used by storing the inputs and the operations one by one. So you get something like 6 + 7 + 5 / 3 =
, and then you break it into its individual components to do the calculation.
The general methodology here is that you want to get a base value, and then iterate on top of it to get your final result. In the first case, this means mutating the value with the same operation for every value. In the second case you tell it the type of mutation that you'd like to perform at every step instead of at the beginning.
If you want to generalise this to used BEDMAS or have more complex functionality, you would probably have to create a tree structure where each node represents an operation and its respective operands, and to get your result you would simply traverse the tree.
e.g. PLUS(PLUS(DIVIDE(5, 3), 7), 6)
Upvotes: 0
Reputation: 349999
You could just keep asking for a number and show the intermediate result at the same time. The user can exit with escape:
var multiply = function () {
var s, ans = 1;
while (s = prompt('Current product is ' + ans +
'. Enter next factor to multiply with, or hit escape to exit')) {
ans *= Number(s);
}
}
multiply();
Upvotes: 0
Reputation: 10899
As stated in other answers you can use the Array.reduce
method. But rather than rolling your own multiplication function you can also use the native Math.imul
method:
var numbers = [1, 2, 3, 4];
var ans = numbers.reduce(Math.imul);
console.log(ans);
Upvotes: 2
Reputation: 1609
You can use reduce function:
[1, 2, 3, 4].reduce(function(a, b) {
return a * b;
}); // it return 24
Btw. in your loop you should push to array in this way:
for(var i = 0; i<times; i++){
numbers.push(Number(prompt("Please, enter one of your numbers")));
}
Upvotes: 2
Reputation: 1546
If I understand you properly you want something like multiply([1, 2, 3, 4]) === 24 ? Then you can use https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
Upvotes: 0