#javascript #arrays #calculator
#javascript #массивы #калькулятор
Вопрос:
Я новичок в JavaScript и пытаюсь разобраться в основах. Теперь я пытаюсь сделать калькулятор. Очень простой, который может складывать, вычитывать, делить и умножать. Я заставил его работать с этим кодом (отображается только умножение:
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();
Моя проблема в том, что я очень ограничен, когда дело доходит до того, сколько чисел пользователь может умножить. Создание варианта переключения для каждого возможного количества займет некоторое время, поэтому я подумал об этом:
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();
Итак, мой вопрос: как я могу заставить «ans» быть равным каждому элементу моего массива «numbers», умноженному друг на друга?
Ответ №1:
Вы можете использовать функцию уменьшения:
[1, 2, 3, 4].reduce(function(a, b) {
return a * b;
}); // it return 24
Кстати. в вашем цикле вы должны нажимать на массив таким образом:
for(var i = 0; i<times; i ){
numbers.push(Number(prompt("Please, enter one of your numbers")));
}
Ответ №2:
Как указано в других ответах, вы можете использовать Array.reduce
метод. Но вместо того, чтобы запускать собственную функцию умножения, вы также можете использовать собственный Math.imul
метод:
var numbers = [1, 2, 3, 4];
var ans = numbers.reduce(Math.imul);
console.log(ans);
Комментарии:
1.
Math.imul
из ES6 и, похоже, обладает некоторыми странными свойствами.(a,b)=>a*b
на 1 символ длиннее.2. @4castle уже есть другие ответы, показывающие функциональное решение (без жирной стрелки), и поскольку OP является новым, я пытался осветить для них другие области JavaScript с соответствующими ссылками, которые подробно описывают, что и как работают эти функции. Не нужно зацикливаться на альтернативных решениях или вступать в войну за количество символов (2 пробела против 4 пробелов и т.д.). 🙂
Ответ №3:
Если я вас правильно понял, вы хотите что-то вроде multiply([1, 2, 3, 4]) === 24 ? Затем вы можете использовать https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
Комментарии:
1. Спасибо! Вы правильно поняли, и ваш метод сработал! Спасибо 🙂
Ответ №4:
Вы могли бы просто продолжать запрашивать число и одновременно показывать промежуточный результат. Пользователь может завершить работу с помощью 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();
Ответ №5:
Уменьшить, вероятно, правильный ответ, но чтобы дать вам более полное представление о том, что он на самом деле делает, взгляните на это. Вот как я бы вручную сделал в основном то же самое, добавив несколько защитных элементов, чтобы сделать это более безопасным.
//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 resu<
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 resu<
}
//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
Вы можете сделать это немного более обобщенным, если хотите сделать что-то подобное…
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 resu<
}
//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
Эта вторая функция будет использоваться путем хранения входных данных и операций по одному. Таким образом, вы получаете что-то вроде 6 7 5 / 3 =
, а затем разбиваете это на отдельные компоненты для выполнения вычисления.
Общая методология здесь заключается в том, что вы хотите получить базовое значение, а затем выполнить итерацию поверх него, чтобы получить конечный результат. В первом случае это означает изменение значения с помощью одной и той же операции для каждого значения. Во втором случае вы указываете ему тип мутации, которую вы хотели бы выполнять на каждом шаге, а не в начале.
Если вы хотите обобщить это на используемые BEDMAS или иметь более сложную функциональность, вам, вероятно, придется создать древовидную структуру, где каждый узел представляет операцию и соответствующие ей операнды, и чтобы получить свой результат, вы просто пройдетесь по дереву.
например PLUS(PLUS(DIVIDE(5, 3), 7), 6)