Как найти сумму массива чисел

483

Учитывая массив [1, 2, 3, 4], как я могу найти сумму его элементов? (В этом случае сумма будет 10.)

Я думал, что $.each может быть полезным, но я не уверен, как его реализовать.

  • 7
    Амир, есть ли шанс изменить принятый ответ? Голосование сообщества довольно подавляющее в пользу другого.
  • 6
    Эмир, пожалуйста , рассмотреть вопрос о принятии @FlorianMargaine «s ответа , а не столь менее эффективный , который вы выбрали.
Показать ещё 3 комментария
Теги:
arrays

36 ответов

976
Лучший ответ

В 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
  • 78
    Да, нет поддержки IE8, jQuery 2+ не работает и в IE8. Давайте не будем обижены действительно дерьмовым браузером. Этот ответ прекрасен. Спасибо, Флориан.
  • 18
    Предполагая, что мы все используем ES2015, мы можем сделать его менее подробным: [1, 2, 3].reduce((a,b)=>a+b)
Показать ещё 17 комментариев
161

Почему бы не уменьшить? Это обычно бит интуитивно понятный, но использование его для поиска суммы довольно просто:

var a = [1,2,3];
var sum = a.reduce(function(a, b) { return a + b; }, 0);
  • 3
    IE8 не поддерживает его, и, похоже, jQuery не собирается его добавлять. Однако, у Прототипа есть это.
  • 4
    @Ishmael, вы можете использовать UnderscoreJS, который прибегает к реализации браузера, если она доступна, или реализует свою собственную в противном случае.
Показать ещё 8 комментариев
132

Рекомендованный (уменьшить значение по умолчанию)

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)
)

Перед функциями стрелок ES6

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

Мы можем использовать 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('+'))

Конечно, отображение предупреждения - это не самое худшее, что может случиться. Единственная причина, по которой я включил это, является ответом на вопрос Ортунда, поскольку я не думаю, что это было выяснено.

  • 9
    Почему ты даже показал путь Eval? У меня наверняка будут кошмары об этом сегодня вечером.
  • 5
    Потому что знание, почему eval не следует часто использовать, стоит больше, чем «просто не используйте его».
Показать ещё 1 комментарий
79
var arr = [1,2,3,4];
var total=0;
for(var i in arr) { total += arr[i]; }
  • 2
    Это намного быстрее, чем решение jQuery.each () выше.
  • 5
    А также не работает в IE9-
Показать ещё 8 комментариев
61
var total = 0;
$.each(arr,function() {
    total += this;
});
  • 77
    Пожалуйста, пожалуйста, используйте ответ с reduce ниже; не объявляйте изменяемые переменные, когда у вас их тоже нет.
  • 9
    Этот ответ находится в стадии обсуждения
Показать ещё 5 комментариев
26

Это возможно, перебирая все элементы и добавляя их на каждой итерации к 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;
}
  • 10
    Будучи умным, я нашел бы код, объявляющий sum вне цикла, гораздо более читабельным.
  • 0
    @ BeniCherniavsky-Paskin Да, то же самое здесь ... Не знаю, почему я сделал это таким образом в тот день ... Тем не менее, я оставлю это как есть! Это просто пример того, как мы могли бы ... ;)
Показать ещё 1 комментарий
23
arr.reduce(function (a, b) {
    return a + b;
});

Ссылка: Array.prototype.reduce()

  • 6
    Это не удастся, если arr равен [] .
  • 7
    Добавьте значение по умолчанию, например, так: arr.reduce(function (a, b) { return a + b; }, 0);
15

Если вы используете Lodash, вы можете использовать функцию sum

array = [1, 2, 3, 4];
sum = _.sum(array);//10
  • 0
    Почему отрицательный голос?
  • 0
    Потому что вы используете _!?
11
// 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 мс/запуск.

  • 1
    Я люблю время, которое вы использовали. Ваш ответ не просто говорит: «Выбери меня, я лучший!» Вместо этого это показывает нам, почему . В любом случае, while (--i) do_something может работать и для других вещей.
  • 0
    var sum = arr[0]
10

Вы также можете использовать 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

  • 0
    Должно быть быстрее в chrome, потому что оптимизация к циклу javascript (т.е. уменьшение длины) также может быть применена к базовой сборке, чтобы она работала быстрее.
10

Кто-нибудь ищет функциональный oneliner, как я? Возьмите это:

sum= arr.reduce(function (a, b) {return a + b;}, 0);
  • 0
    Вы можете добавить начальное значение для arr.reduce(function(a, b) { return a + b;}, 0); как 2-й параметр: arr.reduce(function(a, b) { return a + b;}, 0);
  • 0
    Спасибо! Я включу это.
9

Смешной подход:

eval([1,2,3].join("+"))
  • 5
    Пожалуйста, не могли бы вы расширить этот ответ, объяснив, что происходит в этом коде? Почему это работает? Что именно это делает? Эти вещи помогают улучшить качество ответа.
  • 0
    @ user40521 уже ответил так, как я думаю. Я этого не видел.
Показать ещё 3 комментария
9

Стандартное решение для 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). Надеюсь, в этом решении нет скрытого недостатка.

  • 1
    Кроме того, любой программист на C или Java сможет понять это.
  • 0
    для простого суммирования всех значений простой старый цикл for не имеет конкурентов по времени выполнения
Показать ещё 1 комментарий
5
var totally = eval(arr.join('+'))

Таким образом, вы можете поместить в массив все виды экзотических вещей.

var arr = ['(1/3)','Date.now()','foo','bar()',1,2,3,4]

Я только наполовину шучу.

  • 23
    Я наполовину смеюсь
  • 0
    eval(['alert("removing your computer")',2,3].join("+"))
5

Я начинаю с JavaScript и кодированием вообще, но я обнаружил, что простой и простой способ суммирования чисел в массиве выглядит следующим образом:

    var myNumbers = [1,2,3,4,5]
    var total = 0;
    for(i=0; i<myArray.length; i++){
        total += myArray[i];
    }

В принципе, я хотел внести свой вклад, потому что не видел много решений, которые не используют встроенные функции, и этот метод легко писать и понимать.

4

Несколько человек предложили добавить .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.

4

Короткая часть кода 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)
3

Вы можете комбинировать метод reduce() с выражением лямбда:

[1, 2, 3, 4].reduce((accumulator, currentValue) => accumulator + currentValue);
3

Здесь предлагается элегантное однострочное решение, использующее алгоритм стека, хотя для понимания этой реализации может потребоваться некоторое время.

const getSum = arr => (arr.length === 1) ? arr[0] : arr.pop() + getSum(arr);

getSum([1, 2, 3, 4, 5]) //15

В принципе, функция принимает массив и проверяет, содержит ли массив только один элемент. Если false, он выталкивает последний элемент из стека и возвращает обновленный массив.

Красота этого фрагмента заключается в том, что функция включает arr[0] для предотвращения бесконечного цикла. Как только он достигнет последнего элемента, он возвращает всю сумму.

3

Хорошо, представьте, что у вас есть этот массив ниже:

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...

3

Используйте reduce

let arr = [1, 2, 3, 4];

let sum = arr.reduce((v, i) => (v + i));

console.log(sum);
2

я увидел, что все ответы идут на решение "уменьшить"

var array = [1,2,3,4]
var total = 0
for (var i = 0; i < array.length; i++) {
    total += array[i]
}
console.log(total)
2

Не нужно 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
2

Это намного проще

function sumArray(arr) {
    var total = 0;
    arr.forEach(function(element){
        total += element;
    })
    return total;
}

var sum = sumArray([1,2,3,4])

console.log(sum)
2

Это действительно отличные ответы, но на всякий случай, если числа в последовательности, как в вопросе (1,2,3,4), вы можете легко сделать это, применив формулу (n * (n + 1))/2, где n - последнее число

2

Прохладные трюки здесь, у меня есть выбор нит с множеством безопасных традиционных ответов, не кэширующих длину массива.

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

Возможно, это устаревшее мышление, которое застряло со мной, но я не вижу недостатка в его использовании в этом контексте.

  • 0
    Проблема кэширования длины - красная сельдь. Двигатели JS оптимизируют это для вас, не мигая.
1

Эта функция может суммировать все числа -

 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])
1

Ванильный 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
1

попробуйте это...

function arrSum(arr){
    total = 0;  
    arr.forEach(function(key){
        total = total + key;            
    });
    return total;
}
  • 3
    Пожалуйста, добавьте объяснение к вашему ответу. Ответы только кода не объясняют, как работает код.
1
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
  • 0
    Этот код удаляет вашу операционную систему? Или он отправляет мне вашу личную информацию?
0
    <!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>
0

Просто используйте эту функцию:

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));
0

С параметром останова 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));
-1

Для действительно большого числа циклов или сокращения может быть интенсивным процесс. Как насчет использования Гаусса?

sum = (n * (n+1))/2;

От mathcentral.

  • 0
    Это работает только для последовательных массивов, начинающихся с 1, с шагом 1. Конечно, вопрос OP включает пример, который может сбивать с толку, поскольку [1, 2, 3, 4] соответствует требованиям. Но что, если мы хотим суммировать это: [1, 7, 21, 10009, 300198]?
-1

Использовать рекурсию

var sum = (arr) => arr.length === 1 ? arr[0] : arr.shift() + sum(arr);
sum([1,2,3,4]) // 10
  • 0
    Неразрушающая версия: arr.length === 1 ? arr[0] : arr[0] + sum(arr.slice(1))
-9

Используйте 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();
  • 25
    Это потому, что в этом случае неправильно использовать карту . map map массив элементов где-то, что вы ищете, если вы хотите быть функциональным, так это уменьшить
  • 0
    Кто сказал что-нибудь о функциональности? Или вы имеете в виду функциональность в смысле полезности?
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню