Apa cara tercepat untuk menghitung jumlah kunci / properti suatu objek? Mungkinkah melakukan ini tanpa mengulangi objek? yaitu tanpa melakukan
var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) count++;
(Firefox memang memberikan __count__
properti sulap , tetapi ini dihapus di suatu tempat di sekitar versi 4.)
Jawaban:
Untuk melakukan ini di lingkungan yang kompatibel dengan ES5 , seperti Node , Chrome, IE 9+, Firefox 4+, atau Safari 5+:
sumber
Anda bisa menggunakan kode ini:
Kemudian Anda dapat menggunakan ini di browser lama juga:
sumber
(Object.prototype.hasOwnProperty.call(obj, k))
?hasOwnProperty
perlu dilakukan pengecekan . Ini hanya mengembalikan properti yang ditetapkan pada objek itu sendiri.obj.hasOwnProperty(k)
(saya benar-benar melakukan ini di posting asli saya, tetapi memperbaruinya nanti).hasOwnProperty
tersedia pada setiap objek karena itu adalah bagian dariObject
prototipe, tetapi dalam kejadian langka bahwa metode ini akan dihapus atau diganti Anda mungkin mendapatkan hasil yang tidak terduga. Dengan memanggilnya,Object.prototype
itu membuatnya sedikit lebih kuat. Alasan penggunaannyacall
adalah karena Anda ingin menjalankan metodeobj
alih-alih pada prototipe.Jika Anda menggunakan Underscore.js, Anda dapat menggunakan _.size (terima kasih @douwe):
_.size(obj)
Atau Anda juga dapat menggunakan _.keys yang mungkin lebih jelas untuk beberapa:
_.keys(obj).length
Saya sangat merekomendasikan Underscore, ini adalah perpustakaan yang ketat untuk melakukan banyak hal dasar. Kapan saja mereka cocok dengan ECMA5 dan tunduk pada implementasi asli.
Kalau tidak, saya mendukung jawaban @ Avi. Saya mengeditnya untuk menambahkan tautan ke dokumen MDC yang mencakup metode keys () yang dapat Anda tambahkan ke browser non-ECMA5.
sumber
_.keys(obj).length
bekerja paling baik untuk saya, karena objek pengembalian saya kadang-kadang string polos tanpa properti di dalamnya._.size(obj)
memberi saya kembali panjang string, sementara_.keys(obj).length
mengembalikan 0.Object.keys
internal. Garis bawah juga menyalin setiap kunci ke dalam array di dalamfor..in
loop jikaObject.keys
tidak ditentukan.Implementasi Objek standar ( ES5.1 Objek Properti dan Metode Internal ) tidak memerlukan
Object
untuk melacak jumlah kunci / properti, sehingga tidak boleh ada cara standar untuk menentukan ukuranObject
tanpa berulang-ulang atau tersirat secara implisit atas kunci-kuncinya.Jadi di sini adalah alternatif yang paling umum digunakan:
1. ECMAScript's Object.keys ()
Object.keys(obj).length;
Bekerja dengan pengulangan internal atas kunci untuk menghitung array sementara dan mengembalikan panjangnya.2. Solusi berbasis perpustakaan
Banyak contoh berbasis perpustakaan di tempat lain dalam topik ini adalah idiom yang berguna dalam konteks perpustakaan mereka. Dari sudut pandang kinerja, bagaimanapun, tidak ada untungnya dibandingkan dengan kode tanpa pustaka yang sempurna karena semua metode pustaka tersebut benar-benar merangkum for-loop atau ES5
Object.keys
(asli atau shimmed).3. Mengoptimalkan for-loop
Bagian paling lambat dari for-loop umumnya adalah
.hasOwnProperty()
panggilan, karena fungsi panggilan overhead. Jadi ketika saya hanya ingin jumlah entri objek JSON, saya hanya melewatkan.hasOwnProperty()
panggilan jika saya tahu bahwa tidak ada kode yang juga tidak akan diperpanjangObject.prototype
.Kalau tidak, kode Anda bisa sangat sedikit dioptimalkan dengan membuat
k
local (var k
) dan dengan menggunakan pre-increment operator (++count
) alih-alih postfix.Gagasan lain bergantung pada caching
hasOwnProperty
metode:Apakah ini lebih cepat atau tidak pada lingkungan tertentu adalah masalah pembandingan. Bagaimanapun juga, perolehan kinerja yang sangat terbatas dapat diharapkan.
sumber
var k in myobj
meningkatkan kinerja? Sejauh yang saya tahu, hanya fungsi yang menyatakan ruang lingkup baru dalam JavaScript. Apakah in-loop merupakan pengecualian terhadap aturan ini?for (var k in myobj) hasOwn.call(myobj, k) && ++count;
yaitu mengganti pernyataan if dengan sederhana &&?Object.getOwnPropertyNames(obj).length
:; jauh lebih sederhana.Jika Anda benar-benar mengalami masalah kinerja, saya sarankan membungkus panggilan yang menambah / menghapus properti ke / dari objek dengan fungsi yang juga menambah / mengurangi properti (ukuran?) Yang dinamai dengan tepat.
Anda hanya perlu menghitung jumlah awal properti sekali dan beralih dari sana. Jika tidak ada masalah kinerja aktual, jangan repot-repot. Hanya bungkus sedikit kode itu dalam suatu fungsi
getNumberOfProperties(object)
dan selesai dengan itu.sumber
Seperti yang dinyatakan oleh Avi Flax https://stackoverflow.com/a/4889658/1047014
akan melakukan trik untuk semua properti enumerable pada objek Anda tetapi untuk juga menyertakan properti non-enumerable yang Anda dapat gunakan
Object.getOwnPropertyNames
. Inilah perbedaannya:Seperti yang dinyatakan di sini ini memiliki dukungan browser yang sama dengan
Object.keys
Namun, dalam sebagian besar kasus, Anda mungkin tidak ingin memasukkan yang tidak dapat dihitung dalam jenis operasi ini, tetapi selalu baik untuk mengetahui perbedaannya;)
sumber
Object.getOwnPropertyNames
, Anda adalah satu-satunya di sini ...Saya tidak mengetahui cara apa pun untuk melakukan ini, namun untuk menjaga iterasi seminimal mungkin, Anda dapat mencoba memeriksa keberadaan
__count__
dan jika tidak ada (mis. Bukan Firefox) maka Anda bisa beralih pada objek dan menentukan itu untuk digunakan nanti misalnya:Dengan cara ini setiap pendukung browser
__count__
akan menggunakannya, dan iterasi hanya akan dilakukan untuk mereka yang tidak. Jika jumlah berubah dan Anda tidak bisa melakukan ini, Anda selalu bisa membuatnya berfungsi:Dengan cara ini, kapan saja Anda merujuk myobj.
__count__
fungsi akan diaktifkan dan dihitung ulang.sumber
Object.prototype.__count__
sedang dihapus di Gecko 1.9.3: whereswalden.com/2010/04/06/… count -property-of-objects-is-being-Object.__count__
sudah pergi, dan riddance baik juga.Untuk beralih pada Avi Flax, jawab Object.keys (obj). Panjang sudah benar untuk objek yang tidak memiliki fungsi yang terkait dengannya
contoh:
melawan
langkah-langkah untuk menghindari ini:
jangan letakkan fungsi di objek yang ingin Anda hitung jumlah kunci
menggunakan objek terpisah atau membuat objek baru khusus untuk fungsi (jika Anda ingin menghitung berapa banyak fungsi yang ada dalam file menggunakan
Object.keys(obj).length
)juga ya saya menggunakan modul _ atau garis bawah dari nodejs dalam contoh saya
dokumentasi dapat ditemukan di sini http://underscorejs.org/ serta sumbernya di github dan berbagai info lainnya
Dan akhirnya implementasi lodash https://lodash.com/docs#size
_.size(obj)
sumber
Array(obj).length
: Tidak berfungsi. http://jsfiddle.net/Jhy8M/false
, meskipun saya belum menemukan dokumentasi tentang bagaimanavar obj = { a: true, b: true }
mungkin berbeda darivar obj = {}; obj.a = true; obj.b = true;
atau hanya jika interpretasi / semantik yang berbeda dari W3 memiliki telah diadopsi oleh Chrome.seperti yang dijawab di atas:
Object.keys(obj).length
Tapi: seperti yang kita miliki sekarang kelas Peta nyata di ES6, saya akan menyarankan untuk menggunakannya daripada menggunakan properti dari suatu objek.
sumber
Bagi mereka yang memiliki Underscore.js termasuk dalam proyek mereka yang dapat Anda lakukan:
atau gaya fungsional:
sumber
Berikut adalah beberapa tes kinerja untuk tiga metode;
https://jsperf.com/get-the-number-of-keys-in-an-object
Panjang Object.keys ()
20.735 operasi per detik
Sangat sederhana dan kompatibel. Berjalan cepat tetapi mahal karena itu menciptakan array kunci baru, yang kemudian dibuang.
loop melalui tombol
15.734 operasi per detik
Sedikit lebih lambat, tetapi jauh dari penggunaan memori, jadi mungkin lebih baik jika Anda tertarik untuk mengoptimalkan untuk ponsel atau mesin kecil lainnya
Menggunakan Map, bukan Object
953.839.338 operasi per detik
Pada dasarnya, Peta melacak ukurannya sendiri sehingga kami hanya mengembalikan bidang angka. Jauh, jauh lebih cepat daripada metode lainnya. Jika Anda memiliki kendali atas objek, konversikan mereka ke peta.
sumber
Dari: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
Anda bisa menambahkannya ke semua objek Anda:
Atau satu objek:
Contoh:
Ditambahkan dengan cara itu, itu tidak akan ditampilkan dalam for..in loop:
Keluaran:
Catatan: itu tidak berfungsi di <IE9 browser.
sumber
Bagaimana saya memecahkan masalah ini adalah membangun implementasi saya sendiri dari daftar dasar yang menyimpan catatan tentang berapa banyak item yang disimpan dalam objek. Sangat sederhana. Sesuatu seperti ini:
sumber
var i = basiclist.count
while(i--){...}
add
mengganti item lama atau jikaremove
disebut dengan indeks yang tidak ada. Juga tidak mungkin untuk memeriksa apakah daftar memiliki indeks yang diberikan jikaundefined
merupakan nilai item yang valid.Anda dapat menggunakan
Object.keys(data).length
untuk menemukan panjang objek JSON yang memiliki data kuncisumber
Bagi mereka yang memiliki Ext JS 4 di proyek mereka yang dapat Anda lakukan:
Keuntungan dari ini adalah bahwa ia akan bekerja pada semua browser yang kompatibel dengan Ext (termasuk IE6-IE8), namun, saya percaya waktu yang berjalan tidak lebih baik daripada O (n), seperti solusi yang disarankan lainnya.
sumber
Kamu bisa menggunakan:
dan
sumber
OP tidak menentukan apakah objek tersebut adalah nodeList, jika ya maka Anda bisa langsung menggunakan metode panjang . Contoh:
sumber
Jika jQuery di atas tidak berfungsi, maka coba
sumber
Object.Item
tidak adaSaya tidak berpikir ini mungkin (setidaknya tidak tanpa menggunakan beberapa internal). Dan saya tidak berpikir Anda akan mendapatkan banyak dengan mengoptimalkan ini.
sumber
Saya mencoba membuatnya tersedia untuk semua objek seperti ini:
sumber
Google Penutupan memiliki fungsi yang bagus untuk ini ... goog.object.getCount (obj)
lihat di Goog.Object Documentation
sumber