JavaScript | Как сложить все числа в массиве?

JavaScript | Как сложить все числа в массиве?

Сложение чисел массива методом reduce()

massiv.reduce((a,b)=>a+b)
или
massiv.reduce((a,b)=>b+a)

Мы передаём первым параметром функцию, которая возвращает нам результат сложения предыдущего значения со следующим. При первом вызове предыдущим будет первый элемент массива, а следующим — второй элемент. После первого вызова новый массив уменьшается на один первый элемент. В новом массиве первым элементом становится результат предыдущего вызова коллбэка.

 

Решение для массива из чисел методом map()

massiv.map(i=>x+=i, x=0).reverse()[0]

massiv — это тот массив, на котором мы вызываем методы. То есть тот массив, в котором нужно сложить все числа.

Мы используем второй аргумент функции map(), чтобы создать переменную «над» функцией обратного вызова (над первым аргументом map()). Коллбек будет видеть нашу переменную «x» как внешнюю (объявленную до коллбека), а значит возврат «x+=i» постоянно будет пополнять значение переменной «x».

В это время map() будет вышагивать по элементам оригинального массива и обновлять значение переменной «x». На каждой итерации он будет возвращать текущее значение переменной «x» в новый массив. Когда map() дойдёт до конца, тогда последний элемент нового массива будет хранить в себе сумму всех элементов оригинального массива.

Для простоты доступа к сумме значений мы перевернём новый массив методом reverse(). Последний элемент станет первым. Нам останется только обратиться к первому элементу нового массива. И всё. Готово!

 

…дополнение

Про второй параметр. Про «x=0». Работа JavaScript управляется ГЛОБАЛЬНЫМ объектом. В среде выполнения кода, которая находится в браузере, этим ГЛОБАЛЬНЫМ объектом является объект Window. Из консоли браузера к нему можно обратиться при помощи команды «window».

Так вот когда мы пишем «x=0», в этот момент мы создаём у объекта Window новое свойство, ключом которого является «x», а значением «0».

Если посмотреть на это со стороны, то по сути у нас всегда есть какой-то контейнер для хранения нужных нам данных — это объект Window. И в некоторых случаях нам не обязательно использовать var, let или const для создания отдельных переменных (но есть нюансы!)

Тема с «x=0» осталась не раскрытой. Не все уловили этот момент присваивания.

 

Пример работы — скопируй и вставь в консоль браузера — потестируй!

var massiv = [1,,-1,,111,,2,,-2]
massiv.map(i=>x+=i, x=0).reverse()[0]

111

 

Сложение чисел в массиве на базовых методах языка - JavaScript
Сложение чисел в массиве на базовых методах языка — JavaScript

 

Видео работы через map()

 

Функция с методом map()

function summArrayElements(arr){
  let x = 0;
  return arr.map(i=>x+=i, x).reverse()[0]
}

 

Стабильный способ для массива из чисел

Если элементами массива являются ТОЛЬКО числа, то можно написать функцию и использовать цикл for:

function sum (x){
   var s = 0;
   for (i = 0; i < x.length; i++){
      s += x[i]
   }
   return s
}

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

 

Пробуем передать массив [1, 10, 100, 1000] в функцию.

Функция сложения чисел в массиве - Все элементы числа - JavaScript
Функция сложения чисел в массиве — Все элементы числа — JavaScript

Мы получили ожидаемый результат.

sum([1, 10, 100, 1000])
1111 // результат выполнения функции

Функция хорошо отработала на одном типе данных.

 

Собственный метод для экземпляров Array

Ещё можно расширить набор методов для прототипов Array:

Array.prototype.sum = function(){
   var s = 0;
   for (i = 0; i < this.length; i++){
      s += this[i]
   }
   return s
}

Таким образом мы сможем вызывать наш собственный метод на любом массиве. Но нужно понимать, что в таком виде функция хорошо отрабатывает только тип данных — Number.

[-1, -10, 1, 10, 111].sum()
111 // результат сложения значений элементов массива
[2, 4, 6, 8, 10].sum()
30 // результат суммирования значений элементов массива
Метод sum для прототипов Array - JavaScript
Метод sum для прототипов Array — JavaScript

 

Если в такую функцию передать числа и строки, то получится плохой результат:

[2, 4, "efim360.ru", 8, 10].sum()

Первые два числа в массиве сложатся и мы увидим 6, но как только появится строка, то оператор «+» начнёт конкатенировать все остальные элементы и превращать их в строковые значения. То есть символы начнут слипаться в одну строку. В этом случае результат НЕ будет числом, а это ошибка. Нужно дорабатывать алгоритм и ставить проверку типа данных.

Пример плохой работы функции сложения элементов массива - JavaScript
Пример плохой работы функции сложения элементов массива — JavaScript

 

 

Улучшение № 1 — попытка приведения строки к числу

Может оказаться так, что внутри массива будут строки, которые по факту хранят в себе только цифры и знак минус — (символизирует отрицательное число)

[2, 4, "6", 8, 10, "-10"]

В этом случае нужно попытаться привести строку к числу, а потом сравнить является ли приведённое значение типом Number. Функция будет доработана.

Array.prototype.sum = function(){
   var s = 0;
   for (i = 0; i < this.length; i++){
      s += Number(this[i])
   }
   return s
}

Результат работы:

Метод sum с приведением строки к числу - JavaScript
Метод sum с приведением строки к числу — JavaScript

 

Альтернатива (нерабочее условие — можно не читать)

Array.prototype.sum = function(){
   var s = 0;
   for (i = 0; i < this.length; i++){
      if ( Number(this[i]) == NaN) {continue} // это условие бесполезно, читай ниже "почему?".
      else { s += Number(this[i]) }
   }
   return s
}

Результат работы:

Метод sum обучен переводить строки в числа - JavaScript
Метод sum обучен переводить строки в числа — JavaScript

 

Улучшение № 2 — отбрасывание элементов, которые нельзя привести к числу

Среди строк может оказаться такая, которую нельзя будет привести к числу. Их нужно пропускать.

[2, 4, "6", 8, "JavaScript", 10, "-10"]

Допишем нашу функцию

Array.prototype.sum = function(){
   var s = 0;
   for (i = 0; i < this.length; i++){
      if ( isNaN(this[i]) == true) {continue}
      else { s += Number(this[i]) }
   }
   return s
}

Пример работы:

Функция sum пропускает строки с буквами - JavaScript
Функция sum пропускает строки с буквами — JavaScript

У Глобального Объекта (Global Object) JavaScript есть свои функциональные свойства:

  • eval ( x )
  • isFinite ( number )
  • isNaN ( number )
  • parseFloat ( string )
  • parseInt ( string, radix )
  • Функции обработки URI

Функция isNaN ( number ) — это внутренний объект %isNaN%. Когда функция isNaN вызывается с одним аргументом number, выполняются следующие шаги:

1. Пусть num будет ? ToNumber(number).
2. Если num является NaN, вернуть true.
3. В противном случае вернуть false.

«This is Not a Number?» — расшифровка названия функции. На русском будет звучать так: «Это является Не Числом?«. Под «this/это» подразумевается то, что мы передаём в функцию.

То есть когда мы передадим в функцию isNaN() строку с буквами или прочими символами, тогда абстрактная операция ToNumber (перевод строки в число) вернёт нам NaN — и если это так, то функция isNaN() вернёт true. Условно можно сказать, что попытка отбросить кавычки не сделала из строки число.

Пример работы isNaN - true и false - JavaScript
Пример работы isNaN — true и false — JavaScript

Ещё важно учитывать, что один NaN всегда НЕ равен другому NaN, потому что по сути под любым NaN скрывается какое-то уникальное значение с типом данных Number.

NaN всегда не равен NaN - JavaScript
NaN всегда не равен NaN — JavaScript

Информационные ссылки

JavaScript | Массивы (Array)

Официальная страница стандарта ECMAScript — Раздел «22.1 Array Objects» — https://tc39.es/ecma262/#sec-array-objects

Официальная страница стандарта ECMAScripthttps://tc39.es/ecma262/

Свойства конструктора Array

Свойства объекта прототипа Array

JavaScript | Как сложить все положительные числа в массиве?

JavaScript | Как сложить все отрицательные числа в массиве?

JavaScript | How do I add all the numbers in an array?