Cara menemukan jumlah array angka

809

Diberikan array [1, 2, 3, 4], bagaimana saya bisa menemukan jumlah elemen-elemennya? (Dalam hal ini, jumlahnya akan menjadi 10.)

Saya pikir $.eachmungkin bermanfaat, tetapi saya tidak yakin bagaimana cara mengimplementasikannya.

akano1
sumber
4
Pertanyaan ini sedang dalam diskusi meta
Hantu Madara
18
@ tereško Ketidakmauan ke google bukan alasan tutup yang valid di Stackoverflow. Harap unduh jika Anda merasa bahwa pertanyaannya tidak dicari dengan baik (kembali). (Juga dinilai dari jawaban - ini tampaknya menjadi topik yang sangat kontroversial dengan banyak solusi yang mungkin termasuk beberapa praktik buruk yang sangat tinggi (eval) - mengejutkan.)
Trilarion
8
Catatan: sebagian besar jawaban di sini pada dasarnya menghitung a[0] + a[1] + ..., yang dapat berubah menjadi penggabungan string jika array memiliki elemen non-angka. Misalnya ['foo', 42].reduce((a,b)=>a+b, 0) === "0foo42".
Beni Cherniavsky-Paskin
Tidak ada peredam bawaan yang dapat diumpankan ke Array.reduce? Berpikir sesuatu seperti [1,2,3].reduce(Math.sum).
Phil

Jawaban:

545

Disarankan (kurangi dengan nilai default)

Array.prototype.reduce dapat digunakan untuk beralih melalui array, menambahkan nilai elemen saat ini ke jumlah nilai elemen sebelumnya.

console.log(
  [1, 2, 3, 4].reduce((a, b) => a + b, 0)
)
console.log(
  [].reduce((a, b) => a + b, 0)
)

Tanpa nilai default

Anda mendapatkan TypeError

console.log(
  [].reduce((a, b) => a + b)
)

Sebelum fungsi panah ES6

console.log(
  [1,2,3].reduce(function(acc, val) { return acc + val; }, 0)
)

console.log(
  [].reduce(function(acc, val) { return acc + val; }, 0)
)

Input non-angka

Jika bukan angka adalah input yang mungkin, Anda mungkin ingin mengatasinya?

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

Penggunaan eval berbahaya yang tidak direkomendasikan

Kita dapat menggunakan eval untuk menjalankan representasi string dari kode JavaScript. Menggunakan fungsi Array.prototype.join untuk mengubah array menjadi string, kami mengubah [1,2,3] menjadi "1 + 2 + 3", yang dievaluasi menjadi 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('+'))

Tentu saja menampilkan peringatan bukanlah hal terburuk yang bisa terjadi. Satu-satunya alasan saya memasukkan ini adalah sebagai jawaban pertanyaan Ortund karena saya pikir itu tidak diklarifikasi.

OwChallie
sumber
8
Anda tahu bahwa sihir reduce()ini masih 25-30% lebih lambat daripada for()loop yang diindeks sederhana setelah bertahun-tahun? jsperf.com/reduce-vs-loop/4
tevemadar
Ini menimbulkan masalah jika angkanya "0" - mungkin bisa ditafsirkan sebagai string, untuk alasan apa pun. Menambahkan 1 * a + 1 * b bekerja untuk saya. Mengenai kecepatan, ini lebih mudah untuk ditulis dan saya tidak peduli dengan kecepatannya
Peter Kay
1179

Di Lisp , ini akan menjadi pekerjaan yang tepat reduce. Anda akan melihat kode seperti ini:

(reduce #'+ '(1 2 3)) ; 6

Untungnya, dalam JavaScript, kami juga punya reduce! Sayangnya, +operator, bukan fungsi. Tapi kita bisa membuatnya cantik! Di sini, lihat:

const sum = [1, 2, 3].reduce(add,0); // with initial value to avoid when the array is empty

function add(accumulator, a) {
    return accumulator + a;
}

console.log(sum); // 6

Bukankah itu cantik? :-)

Bahkan lebih baik! Jika Anda menggunakan ECMAScript 2015 (alias ECMAScript 6 ), bisa jadi ini cantik:

const sum = [1, 2, 3].reduce((partial_sum, a) => partial_sum + a,0); 
console.log(sum); // 6
Florian Margaine
sumber
28
Dengan asumsi kita semua menggunakan ES2015, kita dapat membuatnya kurang verbose:[1, 2, 3].reduce((a,b)=>a+b)
Denys Séguret
1
Saya bertanya-tanya apakah waktu eksekusi pengurangan dengan fungsi (a, b) dapat dibandingkan dengan iterasi dan penjumlahan manual atau jika ada beberapa overhead yang cukup besar termasuk?
Trilarion
1
Saya percaya bahwa perlu disebutkan bahwa jawabannya sebenarnya dapat ditemukan pada halaman yang Anda tautkan: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Alex Cohn
2
Saya akan menambahkan beberapa metode ke Array:Array.prototype.sum = function() { return this.reduce((a,b) => a+b, 0); } Array.prototype.avg = function() { return this.reduce((a,b) => a+b, 0)/this.length; }
pilat
2
@ Black mengurangi array menjadi nilai tunggal.
Florian Margaine
205

Kenapa tidak mengurangi? Biasanya sedikit kontra intuitif, tetapi menggunakannya untuk menemukan jumlah cukup mudah:

var a = [1,2,3];
var sum = a.reduce(function(a, b) { return a + b; }, 0);
Casey Rodarmor
sumber
3
IE8 tidak mendukungnya, dan sepertinya jQuery tidak bermaksud menambahkannya. Namun, Prototipe memilikinya.
Ismael Smyrnow
4
@Ishmael, Anda dapat menggunakan UnderscoreJS, yang jatuh kembali ke implementasi browser jika tersedia, atau mengimplementasikan sendiri sebaliknya.
Pablo Diaz
3
Tentang kontra-intuitif reduce()?
kanon
3
@ s4nji Array.prototype.reduce() mengurangi array ke nilai pengembalian tunggal.
kanon
6
@ s4nji ... kecuali Anda mengurangi saus - dalam hal ini Anda membautkannya sampai ke esensi, yaitu jumlah semua rasa tanpa overhead air. :-)
CB Du Rietz
97
var arr = [1,2,3,4];
var total=0;
for(var i in arr) { total += arr[i]; }
Amber
sumber
3
Ini jauh lebih cepat daripada solusi jQuery.each () di atas.
Angry Dan
41
@ Prog: Namun, menggunakan (var i=0; i<arr.length; i++)lebih cepat. Dan bahkan kemudian, menggunakan var sum=0; var i=arr.length; while(i--) sum += arr[i]lebih cepat lagi.
Naik
14
Menggunakan for... inloop pada array berfungsi dalam kasus ini _ kebetulan_ dan karena array memperpanjang objek. Solusi Riking lebih baik
Benjamin Gruenbaum
2
@BenjaminGruenbaum asalkan tidak ada yang menambahkan properti enumerable ke prototipe array ...
canon
1
@YSC tidak, tidak. Sebuah for...inloop dalam JavaScript mengambil indeks, yang merupakan batu sandungan yang umum untuk coders yang mengharapkan untuk mendapatkan nilai. (Coba for(var i in [1,2,3]) { console.log(i); }di konsol.)
Amber
61
var total = 0;
$.each(arr,function() {
    total += this;
});
Tyler Carter
sumber
87
Tolong, tolong, gunakan jawaban di reducebawah ini; jangan mendeklarasikan vars yang bisa berubah ketika Anda tidak memilikinya.
Bruno Grieder
9
Jawaban ini sedang dalam diskusi meta
Hantu Madara
11
Tolong jangan gunakan ini, meskipun itu adalah "jawaban yang diterima"; jawaban Florian di bawah ini jauh lebih baik!
Andy Sinclair
12
@BrunoGrieder "Jangan mendeklarasikan vars yang bisa berubah ketika Anda tidak harus" adalah pendapat yang sangat bias tentang bahasa imperatif , ini bukan bau kode oleh imajinasi. Sama sekali tidak ada yang salah dengan jawaban Tyler, dan satu-satunya perbedaan antara Tyler dan Florian adalah gaya.
Rob
5
Dari OP: Saya pikir $ .each mungkin berguna, tapi saya tidak yakin bagaimana cara mengimplementasikannya. Ini mungkin bukan yang terbaik, tetapi jawab permintaan OP.
33

Jika Anda menggunakan Lodash, Anda bisa menggunakan fungsi penjumlahan

array = [1, 2, 3, 4];
sum = _.sum(array); // sum == 10
David mengatakan Reinstate Monica
sumber
29

Ini dimungkinkan dengan mengulang semua item, dan menambahkannya pada setiap iterasi ke sum-variable.

var array = [1, 2, 3];

for (var i = 0, sum = 0; i < array.length; sum += array[i++]);

JavaScript tidak tahu pencekalan blok, jadi sumdapat diakses:

console.log(sum); // => 6

Sama seperti di atas, namun dijelaskan dan disiapkan sebagai fungsi sederhana:

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;
}
yaart
sumber
12
Meskipun pintar, saya akan menemukan kode yang menyatakan di sumluar loop jauh lebih mudah dibaca.
Beni Cherniavsky-Paskin
@ BeniCherniavsky-Paskin Ya, sama di sini ... Tidak tahu mengapa saya melakukannya dengan cara itu hari itu ... Namun, saya akan membiarkannya apa adanya! Itu hanya contoh bagaimana kita bisa ... ;)
yckart
Sejak ES6, javascript TIDAK mengetahui pelingkupan blok dengan constdan let. Jadi, Anda dapat mendeklarasikan di sumluar forloop sebagai let sum = 0;. Anda juga dapat men-cache panjang array sebelum loop sebagaiconst length = array.length;
KSK
23
arr.reduce(function (a, b) {
    return a + b;
});

Referensi: Array.prototype.reduce ()

onhout
sumber
6
Ini akan gagal jika arrada [].
7
Tambahkan nilai default, seperti:arr.reduce(function (a, b) { return a + b; }, 0);
Ngz
15
// Given array 'arr'
var i = arr.length;
var sum = 0;
while (--i) sum += arr[i];

Ini akan memakan waktu rata-rata 1,57 ms / run (diukur lebih dari 1000 berjalan pada array 100 angka normal acak), dibandingkan dengan 3,604 ms / run dengan eval()metode di atas dan 2,151 ms / run dengan standar untuk (i, panjang, ++ ) loop.

Catatan metodologi: tes ini dijalankan pada server Google Apps Script, jadi mesin javascript mereka hampir sama dengan Chrome.

EDIT: --ibukannya i--menyimpan 0,12 ms setiap kali berjalan (i-- adalah 1,7)

EDIT: Suci sumpah serapah, apalagi posting ini. Gunakan metode pengurangan () yang disebutkan di atas, hanya 1 ms / run.

Bersepeda
sumber
1
Saya suka timing yang Anda gunakan. Jawaban Anda tidak hanya mengatakan, "Pilih aku, aku yang terbaik!" Alih-alih itu menunjukkan kepada kita mengapa . Bagaimanapun, while (--i) do_somethingmungkin bekerja untuk hal-hal lain juga.
Program Redwolf
var sum = arr[0]
noobninja
12

Anda juga dapat menggunakan Kurangi.

[1,2,3,4,5,6].reduceRight(function(a,b){return a+b;})

yang menghasilkan output sebagai 21.

Referensi: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/ReduceRight

Rohit Bhalke
sumber
Seharusnya lebih cepat di chrome karena optimisasi ke javascript looping (mis. Decrementing the length) juga dapat diterapkan pada perakitan yang mendasari untuk membuatnya berjalan lebih cepat.
Jack Giffin
12

Adakah yang mencari oneliner fungsional seperti saya? Ambil ini:

sum= arr.reduce(function (a, b) {return a + b;}, 0);
geek-merlin
sumber
Anda dapat menambahkan nilai awal untuk mengurangi sebagai param 2:arr.reduce(function(a, b) { return a + b;}, 0);
Ngz
Terima kasih! saya akan memasukkan itu.
geek-merlin
12

OK, bayangkan Anda memiliki array ini di bawah ini:

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

Mari kita mulai mencari berbagai cara untuk melakukannya karena saya tidak dapat menemukan jawaban yang komprehensif di sini:

1) Menggunakan pengurangan bawaan ()

function total(arr) {
  if(!Array.isArray(arr)) return;
  return arr.reduce((a, v)=>a + v);
}

2) Menggunakan untuk loop

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

function total(arr) {
  if(!Array.isArray(arr)) return;
  let totalNumber = 0, i=-1;
  while (++i < arr.length) {
     totalNumber+=arr[i];
  }
  return totalNumber;
}

4) Menggunakan array forEach

function total(arr) {
  if(!Array.isArray(arr)) return;
  let sum=0;
  arr.forEach(each => {
    sum+=each;
  });
  return sum;
};

dan menyebutnya seperti ini:

total(arr); //return 10

Tidak disarankan untuk membuat prototipe seperti ini ke Array ...

Alireza
sumber
11

Pendekatan lucu:

eval([1,2,3].join("+"))
elektron
sumber
5
Bisakah Anda memperluas jawaban ini dengan menjelaskan apa yang terjadi dalam kode ini? Mengapa ini berhasil? Apa fungsinya sebenarnya? Hal-hal ini membantu meningkatkan kualitas jawaban.
Ortund
@ user40521 sudah menjawab ini seperti yang saya pikirkan. Saya tidak melihatnya.
elektron
Walaupun ini pendek dan manis, dan tentu saja menarik, itu juga sangat tidak efisien. Menggunakan reducejelas lebih disukai untuk sebagian besar, jika tidak semua, kasus.
Ninjakannon
Errm,[1,"2;YourProgram.ripToShreds();3",4]
Program Redwolf
Jadi saya mendapatkan NaNketika mencoba eval(['alert("removing your computer")',2,3].join("+"))jawaban yang salah 0/10
pie6k
10

Solusi JavaScript standar:

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 */

Ini bekerja untuk saya (hasilnya harus 5). Saya harap tidak ada kerugian tersembunyi dalam solusi semacam ini.

nano
sumber
1
Juga, setiap programmer C atau Java akan dapat memahami ini.
Audrius Meskauskas
untuk tujuan sederhana
merangkum
Satu-satunya masalah adalah, itu agak menjengkelkan ketika Anda memiliki 20 untuk loop semua bersarang satu sama lain
Program Redwolf
7
var totally = eval(arr.join('+'))

Dengan begitu Anda bisa meletakkan segala macam hal eksotis dalam array.

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

Saya hanya setengah bercanda.

pengguna40521
sumber
26
Saya setengah tertawa
caub
eval(['alert("removing your computer")',2,3].join("+"))
pie6k
7

Saya seorang pemula dengan JavaScript dan coding pada umumnya, tetapi saya menemukan bahwa cara sederhana dan mudah untuk menjumlahkan angka-angka dalam array adalah seperti ini:

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

Pada dasarnya, saya ingin berkontribusi ini karena saya tidak melihat banyak solusi yang tidak menggunakan fungsi bawaan, dan metode ini mudah ditulis dan dipahami.

CandyPaintedRIMS
sumber
1
Apa bedanya dengan jawaban tahun 2012 ini atau jawaban tahun 2014 ini ? Ada dua solusi yang belum Anda lihat.
Dan Dascalescu
5

Sepotong kode JavaScript singkat akan melakukan pekerjaan ini:

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)
Timur Zhilenkov
sumber
5

Beberapa orang menyarankan menambahkan .sum()metode ke Array.prototype. Ini umumnya dianggap praktik buruk sehingga saya tidak menyarankan Anda melakukannya.

Jika Anda masih bersikeras melakukannya maka ini adalah cara yang ringkas untuk menuliskannya:

Array.prototype.sum = function() {return [].reduce.call(this, (a,i) => a+i, 0);}

kemudian: [1,2].sum(); // 3

Perhatikan bahwa fungsi yang ditambahkan ke prototipe menggunakan campuran fungsi ES5 dan ES6 dan sintaks panah. The functiondinyatakan untuk memungkinkan metode untuk mendapatkan thiskonteks dari Arrayyang Anda beroperasi pada. Saya menggunakan =>untuk singkatnya dalam reducepanggilan.

Orang
sumber
5

Gunakan satu forlingkaran:

const array = [1, 2, 3, 4];
let result = 0;

for (let i = 0; i < array.length - 1; i++) {
  result += array[i];
}

console.log(result); // Should give 10

Atau bahkan satu forEachloop:

const array = [1, 2, 3, 4];
let result = 0;

array.forEach(number => {
  result += number;
})

console.log(result); // Should give 10

Untuk kesederhanaan, gunakan reduce:

const array = [10, 20, 30, 40];
const add = (a, b) => a + b
const result = array.reduce(add);

console.log(result); // Should give 100
JuicY_Burrito
sumber
4

Tidak perlu initial value! Karena jika tidak initial valuedilewatkan, maka callback functiontidak dipanggil pada elemen pertama dari daftar, dan elemen pertama malah dilewatkan sebagai initial value. Sangat kaya fitur :)

[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
Yas
sumber
4

Berikut adalah solusi one-liner yang elegan yang menggunakan algoritma stack , meskipun orang mungkin perlu waktu untuk memahami keindahan implementasi ini.

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

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

Pada dasarnya, fungsi menerima array dan memeriksa apakah array berisi tepat satu item. Jika salah, ia mengeluarkan item terakhir dari tumpukan dan mengembalikan array yang diperbarui.

Keindahan potongan ini adalah bahwa fungsinya termasuk arr[0]memeriksa untuk mencegah perulangan tak terbatas. Setelah mencapai item terakhir, ia mengembalikan seluruh jumlah.

Rex Low
sumber
4

Anda dapat menggabungkan metode reduce () dengan ekspresi lambda:

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

Menggunakan reduce

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

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

console.log(sum);

Damien Asseya
sumber
3

saya melihat semua jawaban akan solusi 'mengurangi'

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

Ketepatan

Sortir larik dan mulai jumlah penjumlahan dari bilangan terkecil (cuplikan menunjukkan perbedaan dengan nonsort)

[...arr].sort((a,b)=>a-b).reduce((a,c)=>a+c,0)

Untuk penggunaan array angka multidimensi arr.flat(Infinity)

Kamil Kiełczewski
sumber
2

Trik-trik keren di sini, saya punya pilihan nit dengan banyak jawaban tradisional yang aman dan tidak menyimpan panjang array.

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

Tanpa caching panjang array, kompiler JS harus melalui array dengan setiap iterasi dari loop untuk menghitung panjang, itu tidak perlu overhead dalam banyak kasus. V8 dan banyak peramban modern mengoptimalkan ini untuk kami, jadi ini kurang menjadi perhatian dibanding sebelumnya, tetapi ada perangkat yang lebih tua yang mendapat manfaat dari caching sederhana ini.

Jika panjangnya dapat berubah, caching yang dapat menyebabkan beberapa efek samping yang tidak terduga jika Anda tidak tahu mengapa Anda caching panjang, tetapi untuk fungsi yang dapat digunakan kembali yang hanya bertujuan untuk mengambil array dan menambahkan nilai bersama itu adalah sangat cocok.

Inilah tautan CodePen untuk fungsi arraySum ini. http://codepen.io/brandonbrule/pen/ZGEJyV

Mungkin saja ini adalah pola pikir yang sudah ketinggalan zaman yang melekat pada saya, tetapi saya tidak melihat kerugian untuk menggunakannya dalam konteks ini.

Brandon Brule
sumber
Masalah panjang caching adalah herring merah. Mesin JS akan mengoptimalkan ini untuk Anda tanpa berkedip.
2

Itu adalah jawaban yang benar-benar hebat, tetapi untuk jaga-jaga jika angkanya dalam urutan seperti pada pertanyaan (1,2,3,4) Anda dapat dengan mudah melakukannya dengan menerapkan rumus (n * (n + 1)) / 2 di mana n adalah angka terakhir

Santosh
sumber
2
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
ostranenie
sumber
Apakah kode ini menghapus sistem operasi Anda? Atau apakah itu mengirim informasi pribadi Anda kepada saya?
2

Ini jauh lebih mudah

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

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

console.log(sum)
Jakub Gawel
sumber
2

Contoh metode sederhana:

function add(array){
    var arraylength = array.length;
    var sum = 0;
    for(var timesToMultiply = 0; timesToMultiply<arraylength; timesToMultiply++){
        sum += array[timesToMultiply];
    }

    return sum;
}

console.log(add([1, 2, 3, 4]));
Sifiso Nkabinde
sumber