Учитывая массив [1, 2, 3, 4]
, как я могу найти сумму его элементов? (В этом случае сумма будет 10
.)
Я думал, что $.each
может быть полезным, но я не уверен, как его реализовать.
В Lisp это будет именно работа для reduce
. Вы увидите такой код:
(reduce #'+ '(1 2 3)) ; 6
К счастью, в JavaScript мы также имеем reduce
! К сожалению, +
- это оператор, а не функция. Но мы можем сделать это красиво! Вот, посмотрите:
var sum = [1, 2, 3].reduce(add, 0);
function add(a, b) {
return a + b;
}
console.log(sum); // 6
Разве это не так?: -)
Еще лучше! Если вы используете ECMAScript 2015 (aka ECMAScript 6), это может быть довольно красиво:
var sum = [1, 2, 3].reduce((a, b) => a + b, 0);
console.log(sum); // 6
[1, 2, 3].reduce((a,b)=>a+b)
Почему бы не уменьшить? Это обычно бит интуитивно понятный, но использование его для поиска суммы довольно просто:
var a = [1,2,3];
var sum = a.reduce(function(a, b) { return a + b; }, 0);
Array.prototype.reduce может использоваться для итерации по массиву, добавляя текущее значение элемента к сумме предыдущих значений элемента.
console.log(
[1, 2, 3, 4].reduce((a, b) => a + b, 0)
)
console.log(
[].reduce((a, b) => a + b, 0)
)
Вы получаете TypeError
console.log(
[].reduce((a, b) => a + b)
)
console.log(
[1,2,3].reduce(function(acc, val) { return acc + val; }, 0)
)
console.log(
[].reduce(function(acc, val) { return acc + val; }, 0)
)
Если не-номера являются возможными входами, вы можете это обработать?
console.log(
["hi", 1, 2, "frog"].reduce((a, b) => a + b)
)
let numOr0 = n => isNaN(n) ? 0 : n
console.log(
["hi", 1, 2, "frog"].reduce((a, b) =>
numOr0(a) + numOr0(b))
)
Мы можем использовать eval для выполнения строкового представления кода JavaScript. Используя функцию Array.prototype.join для преобразования массива в строку, мы меняем [1,2,3] на "1 + 2 + 3", который оценивается до 6.
console.log(
eval([1,2,3].join('+'))
)
//This way is dangerous if the array is built
// from user input as it may be exploited eg:
eval([1,"2;alert('Malicious code!')"].join('+'))
Конечно, отображение предупреждения - это не самое худшее, что может случиться. Единственная причина, по которой я включил это, является ответом на вопрос Ортунда, поскольку я не думаю, что это было выяснено.
var arr = [1,2,3,4];
var total=0;
for(var i in arr) { total += arr[i]; }
var total = 0;
$.each(arr,function() {
total += this;
});
reduce
ниже; не объявляйте изменяемые переменные, когда у вас их тоже нет.
Это возможно, перебирая все элементы и добавляя их на каждой итерации к sum
-variable.
var array = [1, 2, 3];
for (var i = 0, sum = 0; i < array.length; sum += array[i++]);
JavaScript не знает о масштабах блока, поэтому sum
будет доступной:
console.log(sum); // => 6
То же, что и выше, однако аннотируется и готовится как простая функция:
function sumArray(array) {
for (
var
index = 0, // The iterator
length = array.length, // Cache the array length
sum = 0; // The total amount
index < length; // The "for"-loop condition
sum += array[index++] // Add number on each iteration
);
return sum;
}
sum
вне цикла, гораздо более читабельным.
arr.reduce(function (a, b) {
return a + b;
});
Ссылка: Array.prototype.reduce()
arr
равен []
.
arr.reduce(function (a, b) { return a + b; }, 0);
Если вы используете Lodash, вы можете использовать функцию sum
array = [1, 2, 3, 4];
sum = _.sum(array);//10
// Given array 'arr'
var i = arr.length;
var sum = 0;
while (--i) sum += arr[i];
Это займет в среднем 1,57 мс/прогон (измерено более 1000 прогонов в массиве из 100 случайных нормальных чисел) по сравнению с 3,604 мс/запустит с помощью метода eval()
выше и 2.151 мс/запустит со стандартом для ( i, length, ++).
Примечание по методологии: этот тест был запущен на сервере Google Apps Script, поэтому их механизмы javascript почти такие же, как Chrome.
EDIT: --i
вместо i--
сохраняет 0.12 мс каждый прогон (i-- равен 1.7)
РЕДАКТИРОВАТЬ: Священный казнь, не обращайте внимания на весь этот пост. Использовать метод reduce(), упомянутый выше, всего 1 мс/запуск.
while (--i) do_something
может работать и для других вещей.
var sum = arr[0]
Вы также можете использовать reduceRight.
[1,2,3,4,5,6].reduceRight(function(a,b){return a+b;})
который выводит результат как 21.
Ссылка: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/ReduceRight
Кто-нибудь ищет функциональный oneliner, как я? Возьмите это:
sum= arr.reduce(function (a, b) {return a + b;}, 0);
arr.reduce(function(a, b) { return a + b;}, 0);
как 2-й параметр: arr.reduce(function(a, b) { return a + b;}, 0);
Смешной подход:
eval([1,2,3].join("+"))
Стандартное решение для JavaScript:
var addition = [];
addition.push(2);
addition.push(3);
var total = 0;
for (var i = 0; i < addition.length; i++)
{
total += addition[i];
}
alert(total); // Just to output an example
/* console.log(total); // Just to output an example with Firebug */
Это работает для меня (результат должен быть 5). Надеюсь, в этом решении нет скрытого недостатка.
var totally = eval(arr.join('+'))
Таким образом, вы можете поместить в массив все виды экзотических вещей.
var arr = ['(1/3)','Date.now()','foo','bar()',1,2,3,4]
Я только наполовину шучу.
eval(['alert("removing your computer")',2,3].join("+"))
Я начинаю с JavaScript и кодированием вообще, но я обнаружил, что простой и простой способ суммирования чисел в массиве выглядит следующим образом:
var myNumbers = [1,2,3,4,5]
var total = 0;
for(i=0; i<myArray.length; i++){
total += myArray[i];
}
В принципе, я хотел внести свой вклад, потому что не видел много решений, которые не используют встроенные функции, и этот метод легко писать и понимать.
Несколько человек предложили добавить .sum()
метод Array.prototype
. Это обычно считается плохой практикой, поэтому я не предлагаю, чтобы вы это делали.
Если вы все еще настаиваете на этом, это будет лаконичным способом его написания:
Array.prototype.sum = function() {return [].reduce.call(this, (a,i) => a+i, 0);}
тогда: [1,2].sum(); // 3
Обратите внимание, что функция, добавленная к прототипу, использует смесь функций ES5 и ES6 и синтаксиса стрелок. Объявлен function
, чтобы позволить методу получить this
контекст из Array
, над которым вы работаете. Я использовал =>
для краткости внутри вызова reduce
.
Короткая часть кода JavaScript выполнит эту работу:
var numbers = [1,2,3,4];
var totalAmount = 0;
for (var x = 0; x < numbers.length; x++) {
totalAmount += numbers[x];
}
console.log(totalAmount); //10 (1+2+3+4)
Вы можете комбинировать метод reduce() с выражением лямбда:
[1, 2, 3, 4].reduce((accumulator, currentValue) => accumulator + currentValue);
Здесь предлагается элегантное однострочное решение, использующее алгоритм стека, хотя для понимания этой реализации может потребоваться некоторое время.
const getSum = arr => (arr.length === 1) ? arr[0] : arr.pop() + getSum(arr);
getSum([1, 2, 3, 4, 5]) //15
В принципе, функция принимает массив и проверяет, содержит ли массив только один элемент. Если false, он выталкивает последний элемент из стека и возвращает обновленный массив.
Красота этого фрагмента заключается в том, что функция включает arr[0]
для предотвращения бесконечного цикла. Как только он достигнет последнего элемента, он возвращает всю сумму.
Хорошо, представьте, что у вас есть этот массив ниже:
const arr = [1, 2, 3, 4];
Давайте начнем изучать разные способы сделать это, так как я не нашел исчерпывающего ответа здесь:
1) Использование встроенного сокращения()
function total(arr) {
if(!Array.isArray(arr)) return;
return arr.reduce((a, v)=>a + v);
}
2) Использование для цикла
function total(arr) {
if(!Array.isArray(arr)) return;
let totalNumber = 0;
for (let i=0,l=arr.length; i<l; i++) {
totalNumber+=arr[i];
}
return totalNumber;
}
3) Использование цикла while
function total(arr) {
if(!Array.isArray(arr)) return;
let totalNumber = 0, i=-1;
while (++i < arr.length) {
totalNumber+=arr[i];
}
return totalNumber;
}
4) Использование массива forEach
function total(arr) {
if(!Array.isArray(arr)) return;
let sum=0;
arr.forEach(each => {
sum+=each;
});
return sum;
};
и назовите его так:
total(arr); //return 10
Не рекомендуется прототипировать что-то подобное в Array...
Используйте reduce
let arr = [1, 2, 3, 4];
let sum = arr.reduce((v, i) => (v + i));
console.log(sum);
я увидел, что все ответы идут на решение "уменьшить"
var array = [1,2,3,4]
var total = 0
for (var i = 0; i < array.length; i++) {
total += array[i]
}
console.log(total)
Не нужно initial value
! Поскольку, если no initial value
передано, callback function
не вызывается в первом элементе списка, а первый элемент вместо этого передается как initial value
. Очень c OO l функция:)
[1, 2, 3, 4].reduce((a, x) => a + x) // 10
[1, 2, 3, 4].reduce((a, x) => a * x) // 24
[1, 2, 3, 4].reduce((a, x) => Math.max(a, x)) // 4
[1, 2, 3, 4].reduce((a, x) => Math.min(a, x)) // 1
Это намного проще
function sumArray(arr) {
var total = 0;
arr.forEach(function(element){
total += element;
})
return total;
}
var sum = sumArray([1,2,3,4])
console.log(sum)
Это действительно отличные ответы, но на всякий случай, если числа в последовательности, как в вопросе (1,2,3,4), вы можете легко сделать это, применив формулу (n * (n + 1))/2, где n - последнее число
Прохладные трюки здесь, у меня есть выбор нит с множеством безопасных традиционных ответов, не кэширующих длину массива.
function arraySum(array){
var total = 0,
len = array.length;
for (var i = 0; i < len; i++){
total += array[i];
}
return total;
};
var my_array = [1,2,3,4];
// Returns 10
console.log( arraySum( my_array ) );
Без кэширования длины массива компилятор JS должен проходить через массив с каждой итерацией цикла для вычисления длины, в большинстве случаев это лишние накладные расходы. V8 и многие современные браузеры оптимизируют это для нас, поэтому это меньше беспокоит, чем это было, но есть более старые устройства, которые извлекают выгоду из этого простого кэширования.
Если длина может быть изменена, кеширование может вызвать некоторые неожиданные побочные эффекты, если вы не знаете, почему вы кешируете длину, но для функции многократного использования, которая предназначена только для того, чтобы взять массив и добавить значения вместе это очень удобно.
Здесь ссылка CodePen для этой функции arraySum. http://codepen.io/brandonbrule/pen/ZGEJyV
Возможно, это устаревшее мышление, которое застряло со мной, но я не вижу недостатка в его использовании в этом контексте.
Эта функция может суммировать все числа -
function array(arr){
var sum = 0;
for (var i = 0; i< arr.length; i++){
sum += arr[i];
}
console.log(sum);
}
array([5, 1, 3, 3])
Ванильный JavaScript - это все, что вам нужно:
> a = [1,2,3,4]; a.foo = 5; a['bar'] = 6; sum = 0; a.forEach(function(e){sum += e}); sum
10
> a = [1,2,3,4]; a.foo = 5; a['bar'] = 6; sum = 0; a.forEach(e => sum += e); sum
10
> a = [1,2,3,4]; a.foo = 5; a['bar'] = 6; sum = 0; for(e in a) sum += e; sum
"00123foobar"
> a = [1,2,3,4]; a.foo = 5; a['bar'] = 6; sum = 0; for(e of a) sum += e; sum
10
попробуйте это...
function arrSum(arr){
total = 0;
arr.forEach(function(key){
total = total + key;
});
return total;
}
Object.defineProperty(Object.prototype, 'sum', {
enumerable:false,
value:function() {
var t=0;for(var i in this)
if (!isNaN(this[i]))
t+=this[i];
return t;
}
});
[20,25,27.1].sum() // 72.1
[10,"forty-two",23].sum() // 33
[Math.PI,0,-1,1].sum() // 3.141592653589793
[Math.PI,Math.E,-1000000000].sum() // -999999994.1401255
o = {a:1,b:31,c:"roffelz",someOtherProperty:21.52}
console.log(o.sum()); // 53.519999999999996
<!DOCTYPE html>
<html>
<body>
<p>Click the button to join two arrays.</p>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
<script>
var hege = [1, 2,4,6,7,8,8];
var stale = [1, 2,4,5];
function myFunction() {
console.log((hege.length > stale.length))
var children = (hege.length > stale.length)? abc1() :abc2(); document.getElementById("demo").innerHTML = children;
}
function abc1(){
console.log(hege,"Abc1")
var abcd=hege.map(function (num, idx) {
console.log(hege.length , idx)
return stale.length>idx?num + stale[idx]:num;
})
return abcd;
}
function abc2(){
console.log(hege,"Abc2",stale)
var abcd=stale.map(function (num, idx) {
console.log(hege.length , idx)
return hege.length>idx?num + hege[idx]:num;
})
return abcd;
}
</script>
</body>
</html>
Просто используйте эту функцию:
function sum(pArray)
{
pArray = pArray.reduce(function (a, b) {
return a + b;
}, 0);
return pArray;
}
function sum(pArray)
{
pArray = pArray.reduce(function (a, b) {
return a + b;
}, 0);
return pArray;
}
var arr = [1, 4, 5];
console.log(sum(arr));
С параметром останова ES6
let array = [1, 2, 3, 4]
function sum(...numbers) {
let total = 0;
for (const number of numbers) {
total += number;
}
return total;
}
console.log(sum(...array));
Для действительно большого числа циклов или сокращения может быть интенсивным процесс. Как насчет использования Гаусса?
sum = (n * (n+1))/2;
От mathcentral.
Использовать рекурсию
var sum = (arr) => arr.length === 1 ? arr[0] : arr.shift() + sum(arr);
sum([1,2,3,4]) // 10
arr.length === 1 ? arr[0] : arr[0] + sum(arr.slice(1))
Используйте map
:
var sum = 0;
arr.map(function(item){
sum += item;
});
// sum now contains the total.
Вы могли бы добавить метод в прототип Array.
Array.prototype.sum = function(){
var sum = 0;
this.map(function(item){
sum += item;
});
return sum;
}
Затем вы можете использовать его на любом массиве, например:
arr.sum();