Saya memiliki sebuah array:
[1, 2, 3, 5, 2, 8, 9, 2]
Saya ingin tahu berapa banyak 2
yang ada dalam array.
Apa cara paling elegan untuk melakukannya dalam JavaScript tanpa mengulang dengan for
loop?
javascript
Leem
sumber
sumber
const count = countItems(array, 2);
dan detail implementasi dapat diperdebatkan di dalamnya.[ jawaban ini sedikit bertanggal: baca hasil edit ]
Katakan halo kepada teman-teman Anda:
map
danfilter
danreduce
danforEach
danevery
sebagainya.(Saya hanya sesekali menulis for-loop dalam javascript, karena pelingkupan tingkat blok tidak ada, jadi Anda harus tetap menggunakan fungsi sebagai badan loop jika Anda perlu menangkap atau mengkloning indeks atau nilai iterasi Anda. For-loop lebih efisien secara umum, tetapi kadang-kadang Anda perlu penutupan.)
Cara yang paling mudah dibaca:
(Kita bisa menulis
.filter(function(x){return x==2}).length
sebagai gantinya)Berikut ini lebih hemat ruang (O (1) daripada O (N)), tapi saya tidak yakin berapa banyak manfaat / penalti yang mungkin Anda bayarkan dalam hal waktu (tidak lebih dari faktor konstan sejak Anda mengunjungi setiap elemen tepat sekali):
(Jika Anda perlu mengoptimalkan bagian kode ini, perulangan for mungkin lebih cepat di beberapa peramban ... Anda dapat menguji berbagai hal di jsperf.com.)
Anda kemudian dapat menjadi elegan dan mengubahnya menjadi fungsi prototipe:
Seperti ini:
Anda juga dapat menempel teknik for-loop lama yang biasa (lihat jawaban lain) di dalam definisi properti di atas (sekali lagi, itu kemungkinan akan jauh lebih cepat).
Sunting 2017 :
Aduh, jawaban ini lebih populer daripada jawaban yang benar. Sebenarnya, gunakan saja jawaban yang diterima. Sementara jawaban ini mungkin lucu, kompiler js mungkin tidak (atau tidak bisa karena spek) mengoptimalkan kasus tersebut. Jadi, Anda harus benar-benar menulis simpel untuk loop:
Anda dapat menentukan versi
.countStrictEq(...)
yang menggunakan===
gagasan persamaan. Gagasan kesetaraan mungkin penting untuk apa yang Anda lakukan! (misalnya[1,10,3,'10'].count(10)==2
, karena angka-angka seperti '4' == 4 dalam javascript ... maka memanggilnya.countEq
atau.countNonstrict
menekankan itu menggunakan==
operator.)Juga pertimbangkan untuk menggunakan struktur data multiset Anda sendiri (misalnya seperti python '
collections.Counter
') untuk menghindari keharusan melakukan penghitungan di tempat pertama.Demo:
sidenote: Meskipun, jika Anda masih menginginkan cara pemrograman fungsional (atau pelepasan one-liner tanpa mengesampingkan Array.prototype), Anda dapat menuliskannya dengan lebih singkat saat ini sebagai
[...].filter(x => x==2).length
. Jika Anda peduli dengan kinerja, perhatikan bahwa sementara ini asimptotik kinerja yang sama dengan waktu for-loop (O (N)), mungkin memerlukan O (N) memori tambahan (bukan memori O (1)) karena akan hampir tentu menghasilkan array perantara dan kemudian menghitung elemen-elemen array menengah itu.sumber
array.reduce(function(total,x){return x==value? : total+1 : total}, 0)
[...].reduce(function(total,x){return x==2 ? total+1 : total}, 0)
const count = (list) => list.filter((x) => x == 2).length
. Kemudian gunakan dengan memanggil dicount(list)
mana daftar adalah array angka. Anda juga bisa melakukanconst count = (list) => list.filter((x) => x.someProp === 'crazyValue').length
untuk menghitung instance crazyValue dalam array objek. Catatan, ini adalah pencocokan tepat untuk properti.ES6 Pembaruan ke JS:
Perhatikan bahwa Anda harus selalu menggunakan triple sama dengan:
===
untuk mendapatkan perbandingan yang benar:Fungsi Panah dengan suara bulat berikut (fungsi lambda) di JS:
dapat disederhanakan ke formulir ringkas ini untuk satu input:
dimana
return
tersirat.sumber
2017: Jika seseorang masih tertarik dengan pertanyaan itu, solusi saya adalah sebagai berikut:
sumber
Jika Anda menggunakan lodash atau garis bawah metode _.countBy akan memberikan objek total agregat yang dikunci oleh setiap nilai dalam array. Anda bisa mengubahnya menjadi satu-liner jika Anda hanya perlu menghitung satu nilai:
Ini juga berfungsi dengan baik pada array angka. Satu-liner untuk contoh Anda adalah:
sumber
Cara teraneh yang bisa saya pikirkan untuk melakukan ini adalah:
Dimana:
Saran saya, gunakan sebentar atau untuk loop ;-)
sumber
Tidak menggunakan loop biasanya berarti menyerahkan proses ke beberapa metode yang tidak menggunakan loop.
Inilah cara loop kita yang membenci coder dapat memuaskan kebenciannya, dengan harga:
Anda juga dapat berulang kali memanggil indexOf, jika tersedia sebagai metode array, dan memindahkan pointer pencarian setiap kali.
Ini tidak membuat array baru, dan loop lebih cepat dari forEach atau filter.
Ini bisa membuat perbedaan jika Anda memiliki sejuta anggota untuk melihatnya.
sumber
String(a).match(/2/g).length + 1
- meskipun waspadai ini atau implementasi Anda tidak akan bermain bagus dengan dua digitSebagian besar solusi yang diposting menggunakan fungsi array seperti filter tidak lengkap karena tidak parameter.
Ini dia solusi untuk menghitung elemen yang bisa diatur pada saat run time.
Keuntungan dari pendekatan ini adalah dapat dengan mudah mengubah fungsi untuk menghitung misalnya jumlah elemen lebih besar dari X.
Anda juga dapat mendeklarasikan fungsi pengurangan sebaris
sumber
var elementToFind=2; ... function (elementToFind, total, number){ return total += number==elementToFind; }.bind(this, elementToFind) ...
lebih sulit untuk dibaca dan tidak memberikan keuntungan lebih dari adil... (acc, x) => acc += number == 2...
. Saya suka penggunaan Anda+=
alih-alihacc + (number == 2)
. Terasa seperti sintaks yang tidak beralasan HACK.Sungguh, mengapa Anda perlu
map
ataufilter
untuk ini?reduce
"dilahirkan" untuk operasi semacam ini:[1, 2, 3, 5, 2, 8, 9, 2].reduce( (count,2)=>count+(item==val), 0);
itu dia! (jika
item==val
dalam setiap iterasi, maka 1 akan ditambahkan ke akumulatorcount
, seperti yangtrue
akan diselesaikan1
).Sebagai fungsi:
Atau, lanjutkan dan rentangkan array Anda:
sumber
Lebih baik membungkusnya menjadi fungsi:
sumber
Berikut adalah cara ES2017 + untuk mendapatkan jumlah semua item array di O (N):
Anda juga dapat secara opsional mengurutkan output:
console.log (countsSorted) untuk contoh array Anda:
sumber
Saya percaya apa yang Anda cari adalah pendekatan fungsional
elem === 'a' adalah syaratnya, ganti dengan milikmu.
sumber
count = arr.filter(elem => elem === 'a').length
ataucount = arr.filter(elem => {return elem === 'a'}).length
Saya penggemar berat fungsi js array.
Bahkan jika Anda benar-benar ingin menjadi mewah, Anda dapat membuat fungsi hitungan pada prototipe Array. Maka Anda dapat menggunakannya kembali.
Lalu lakukan
sumber
Solusi dengan rekursi
sumber
filter
,reduce
atau yang sederhanaforLoop
, dan juga, lebih mahal ketika melihat kinerja, tetapi masih cara yang bagus untuk melakukannya dengan rekursi. Satu-satunya perubahan saya adalah: Saya hanya berpikir akan lebih baik untuk membuat fungsi dan menambahkan filter di dalamnya untuk menyalin array dan menghindari mutasi dari array asli, kemudian menggunakan rekursif sebagai fungsi dalam.Saya akan melakukan sesuatu seperti itu:
sumber
Buat metode baru untuk kelas Array dalam file tingkat inti dan gunakan di seluruh proyek Anda.
Gunakan ini di mana saja dalam proyek Anda -
sumber
Berikut ini adalah satu liner di javascript.
(v === 2)
dalam array, kembalikan array yang dan nol.Hasilnya adalah
3
.sumber
Bergantung pada bagaimana Anda ingin menjalankannya:
sumber
Anda dapat menggunakan properti length dalam array JavaScript:
sumber