Dalam Javascript, saya mencoba mengambil larik awal nilai angka dan menghitung elemen di dalamnya. Idealnya, hasilnya adalah dua array baru, yang pertama menentukan setiap elemen unik, dan yang kedua berisi berapa kali setiap elemen terjadi. Namun, saya terbuka untuk saran tentang format output.
Misalnya, jika array awal adalah:
5, 5, 5, 2, 2, 2, 2, 2, 9, 4
Kemudian dua array baru akan dibuat. Yang pertama akan berisi nama setiap elemen unik:
5, 2, 9, 4
Yang kedua akan berisi berapa kali elemen itu terjadi dalam array awal:
3, 5, 1, 1
Karena angka 5 muncul tiga kali dalam array awal, angka 2 muncul lima kali dan 9 dan 4 keduanya muncul sekali.
Saya telah mencari banyak solusi, tetapi sepertinya tidak ada yang berhasil, dan semua yang saya coba sendiri akhirnya menjadi sangat rumit. Bantuan apa pun akan dihargai!
Terima kasih :)
sumber
if (arr.indexOf(value) == arr.lastIndexOf(value))
ramda.js
untuk mencapai ini dengan cara mudah.const ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary)
arr.filter(x => x===5).length
akan kembali3
untuk menunjukkan bahwa ada 'lima' lima dalam array.Jawaban:
Ini dia:
Demo langsung: http://jsfiddle.net/simevidas/bnACW/
sumber
O(N log(N))
dan keuntungan keanggunan tidak sepadanreduce
jawabannya. Saya akan mengirimkan jawaban seperti itu sebelum saya melihatnya sudah ada. Meskipun demikiancounts[num] = counts[num] ? counts[num]+1 : 1
jawabannya juga bekerja (setara denganif(!result[a[i]])result[a[i]]=0
jawaban, yang lebih elegan tetapi kurang mudah dibaca); jawaban ini dapat dimodifikasi untuk menggunakan versi "lebih bagus" dari for loop, mungkin pihak ketiga untuk-loop, tapi saya agak mengabaikan itu karena for-loop berbasis indeks standar sayangnya adalah default.Anda dapat menggunakan objek untuk menyimpan hasil:
Jadi, sekarang objek hitungan Anda dapat memberi tahu Anda apa hitungannya untuk nomor tertentu:
Jika Anda ingin mendapatkan array anggota, cukup gunakan
keys()
fungsinyasumber
Object.keys()
fungsi itu hanya didukung di IE9 +, FF4 +, SF5 +, CH6 + tetapi Opera tidak mendukungnya. Saya pikir show stopper terbesar di sini adalah IE9 + .counts[num] = (counts[num] || 0) + 1
. Dengan begitu Anda hanya perlu menuliscounts[num]
dua kali alih-alih tiga kali pada satu baris di sana.[5, "5"]
hanya akan mengatakan Anda punya"5"
dua kali. Atau menghitung contoh beberapa objek berbeda hanya akan memberi tahu Anda ada banyak[object Object]
. Dll dll.sumber
acc[curr] ? acc[curr]++ : acc[curr] = 1;
const keys = Object.keys(a);
const values = Object.values(a);
Jika menggunakan garis bawah atau lodash, ini adalah hal paling sederhana untuk dilakukan:
Seperti yang:
Seperti yang ditunjukkan oleh orang lain, Anda kemudian dapat menjalankan
_.keys()
dan_.values()
berfungsi pada hasil untuk mendapatkan hanya angka unik, dan kemunculannya, masing-masing. Tetapi dalam pengalaman saya, objek aslinya jauh lebih mudah untuk ditangani.sumber
Jangan gunakan dua array untuk hasilnya, gunakan objek:
Maka
result
akan terlihat seperti:sumber
Bagaimana dengan opsi ECMAScript2015.
Contoh ini meneruskan array input ke
Set
konstruktor yang membuat koleksi nilai unik . The spread sintaks kemudian memperluas nilai-nilai ini ke dalam array baru sehingga kita dapat memanggilmap
dan menerjemahkan ini ke dalam array dua dimensi dari[value, count]
pasangan - yaitu struktur sebagai berikut:Array baru kemudian diteruskan ke
Map
konstruktor yang menghasilkan objek yang dapat diubah :Hal yang hebat tentang suatu
Map
objek adalah ia mempertahankan tipe-data - artinyaaCount.get(5)
akan kembali3
tetapiaCount.get("5")
akan kembaliundefined
. Ini juga memungkinkan untuk setiap nilai / tipe untuk bertindak sebagai makna kunci solusi ini juga akan berfungsi dengan berbagai objek.Tampilkan cuplikan kode
sumber
Set
menggunakan referensi objek untuk keunikan dan tidak menawarkan API untuk perbandingan objek "serupa" . Jika Anda ingin menggunakan pendekatan ini untuk tugas semacam itu, Anda memerlukan beberapa fungsi reduksi menengah yang menjamin berbagai instance unik. Ini bukan yang paling efisien tetapi saya mengumpulkan contoh cepat di sini .Saya pikir ini adalah cara paling sederhana bagaimana menghitung kejadian dengan nilai yang sama dalam array.
sumber
a.filter(value => !value).length
dengan sintaks js baruSolusi ES6 satu jalur. Begitu banyak jawaban menggunakan objek sebagai peta tetapi saya tidak dapat melihat siapa pun menggunakan Peta yang sebenarnya
Gunakan
map.keys()
untuk mendapatkan elemen unikGunakan
map.values()
untuk mendapatkan kejadianGunakan
map.entries()
untuk mendapatkan pasangan [elemen, frekuensi]sumber
sumber
Jika Anda menyukai satu liner.
arr.reduce(function(countMap, word) {countMap[word] = ++countMap[word] || 1;return countMap}, {});
Edit (6/12/2015) : Penjelasan dari dalam ke luar. countMap adalah peta yang memetakan sebuah kata dengan frekuensinya, yang dapat kita lihat fungsi anonimnya. Apa yang dikurangi adalah menerapkan fungsi dengan argumen karena semua elemen array dan countMap diteruskan sebagai nilai balik dari panggilan fungsi terakhir. Parameter terakhir ({}) adalah nilai default countMap untuk panggilan fungsi pertama.
sumber
;
,{
dan}
. ... BAIK. Saya pikir dengan definisi one liner kita bisa menulis Game of Conway's Life sebagai "oneliner".Versi ES6 harus lebih sederhana (solusi satu baris lainnya)
Peta bukan Objek biasa yang membantu kita membedakan berbagai jenis elemen, atau semua penghitungan didasarkan pada string
sumber
Jika Anda menggunakan garis bawah Anda dapat memilih rute fungsional
jadi array pertama Anda adalah
dan array kedua adalah
sebagian besar ini akan default ke fungsi javascript asli jika tersedia
demo: http://jsfiddle.net/dAaUU/
sumber
Berdasarkan jawaban dari @adamse dan @pmandell (yang saya upvote), di ES6 Anda dapat melakukannya dalam satu baris :
||
untuk mengurangi ukuran kode dan membuatnya lebih mudah dibaca.Ini dapat digunakan untuk menghitung karakter :
sumber
|| 0
:(r,k)=>{r[k]=(r[k]||0)+1;return r}
Ini ada sesuatu yang ringan dan mudah bagi mata ...
Sunting: Dan karena Anda ingin semua kejadian ...
sumber
Jadi, inilah cara saya melakukannya dengan beberapa fitur javascript terbaru:
Pertama, kurangi array ke
Map
hitungan:Dengan menggunakan
Map
, array awal Anda dapat berisi semua jenis objek, dan jumlah akan benar. Tanpa aMap
, beberapa jenis objek akan memberi Anda jumlah aneh. LihatMap
dokumen untuk info lebih lanjut tentang perbedaan.Ini juga bisa dilakukan dengan objek jika semua nilai Anda adalah simbol, angka, atau string:
Atau sedikit lebih keren dengan cara fungsional tanpa mutasi, menggunakan sintaksis dan penyebaran objek sintaksis:
Pada titik ini, Anda dapat menggunakan
Map
objek atau untuk jumlah Anda (dan peta secara langsung dapat diubah, tidak seperti objek), atau mengonversinya menjadi dua array.Untuk
Map
:Atau untuk objek:
sumber
sumber
Map
, karena itu akan menghindari typecasting yang menggunakan angka sebagai kunci objek (casting sebagai string).const answer = array.reduce((a, e) => a.set(e, (a.get(e) || 0) + 1), new Map())
Anda bisa mendapatkananswer.keys()
untuk kunci, dananswer.values()
untuk nilai-nilai sebagai array.[...answer]
akan memberi Anda array besar dengan semua kunci / nilai sebagai array 2d.Solusi ES6 dengan mengurangi (diperbaiki):
sumber
Sunting 2020 : ini adalah jawaban yang cukup lama (sembilan tahun). Memperluas asli
prototype
akan selalu menghasilkan diskusi . Meskipun saya pikir programmer bebas untuk memilih gaya pemrogramannya sendiri, berikut ini adalah pendekatan (yang lebih modern) untuk masalah tanpa memperluasArray.prototype
:Jawaban lama (2011): Anda dapat memperluas
Array.prototype
, seperti ini:Tampilkan cuplikan kode
sumber
Solusi saya dengan ramda:
Tautan ke REPL.
sumber
Solusi menggunakan peta dengan kompleksitas waktu O (n) .
Demo: http://jsfiddle.net/simevidas/bnACW/
sumber
Ada cara yang jauh lebih baik dan mudah yang bisa kita lakukan dengan menggunakan ini
ramda.js
. Contoh kode di siniconst ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary)
Dokumentasi countBy ada di dokumentasisumber
Menggunakan MAP Anda dapat memiliki 2 array di output: Satu berisi kejadian & yang lainnya berisi jumlah kejadian.
sumber
Lihatlah kode di bawah ini.
sumber
Coba ini:
sumber
Saya sedang memecahkan masalah yang sama pada codewars dan menemukan solusi berikut yang bekerja untuk saya.
Ini memberikan jumlah integer tertinggi dalam array dan juga integer itu sendiri. Saya pikir itu bisa diterapkan ke array string juga.
Untuk mengurutkan String dengan benar, hapus
function(a, b){return a-b}
dari dalamsort()
bagian itusumber
Berikut adalah cara untuk menghitung kejadian di dalam array objek. Itu juga menempatkan isi array pertama di dalam array baru untuk mengurutkan nilai-nilai sehingga urutan dalam array asli tidak terganggu. Kemudian fungsi rekursif digunakan untuk menelusuri setiap elemen dan menghitung properti kuantitas dari setiap objek di dalam array.
sumber
sumber
sumber
Pertanyaan ini sudah berusia lebih dari 8 tahun dan banyak, banyak jawaban tidak benar - benar memperhitungkan ES6 dan banyak keuntungannya.
Mungkin lebih penting untuk memikirkan konsekuensi dari kode kami untuk pengumpulan sampah / manajemen memori setiap kali kita membuat array tambahan, membuat salinan array dua atau tiga array atau bahkan mengubah array menjadi objek. Ini adalah pengamatan sepele untuk aplikasi kecil tetapi jika skala adalah tujuan jangka panjang maka pikirkan tentang ini, secara menyeluruh.
Jika Anda hanya memerlukan "penghitung" untuk tipe data tertentu dan titik awalnya adalah sebuah array (saya berasumsi bahwa Anda ingin daftar yang diurutkan dan mengambil keuntungan dari banyak properti dan metode yang ditawarkan array), Anda dapat dengan mudah beralih melalui array1 dan mengisi array2 dengan nilai-nilai dan jumlah kemunculan untuk nilai-nilai ini ditemukan di array1.
Sesimpel itu.
Contoh kelas sederhana SimpleCounter (ES6) untuk Pemrograman Berorientasi Objek dan Desain Berorientasi Objek
sumber
finalList
tidak memiliki alasan untuk menjadi array, dan ini tidak memiliki kelebihan dibandingkan melakukannya dengan benar.Berikut adalah metode jadul klasik untuk menghitung array.
Anda dapat mengurutkannya terlebih dahulu jika Anda menginginkan hasil alfabet, tetapi jika Anda ingin mempertahankan urutan pemasukan data, maka cobalah. Loop bersarang mungkin sedikit lebih lambat daripada beberapa metode lain di halaman ini.
sumber