Mai mult
Cum să eficient conta numărul de chei/de proprietăți a unui obiect în JavaScript?
Ce's cel mai rapid mod de a conta numărul de chei/de proprietăți a unui obiect? Este posibil să facă acest lucru fără iterarea peste obiect? adică, fără a face
var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) count++;
(Firefox făcut oferi o magiecount proprietate, dar acest lucru a fost scos pe undeva pe versiunea 4.)
1444
21
Pentru a face acest lucru în orice ES5-compatibil mediu, precum Nod, Chrome, IE 9+, Firefox 4+, Safari 5+:
Ai putea folosi acest cod:
Apoi puteți folosi acest lucru în browsere mai vechi precum:
Dacă utilizați Underscore.js puteți utiliza _.size (multumesc @douwe):
_.dimensiune(obj)
Alternativ, puteți utiliza, de asemenea, _.chei care ar putea fi mai clar pentru unii:
_.cheile(obj).lungime
Am foarte recomanda Subliniere, sa o strâns bibliotecă pentru a face o mulțime de lucruri de bază. Ori de câte ori este posibil se potrivesc ECMA5 și amâna la punerea în aplicare nativ.
În caz contrar, susțin @Avi's a răspunde. Am editat pentru a adăuga un link la MDC doc care include cheile() metodă, puteți adăuga la non-ECMA5 browsere.
Standard Obiect de punere în aplicare (ES5.1 Obiect Intern Proprietăți și Metode) nu are nevoie de un "Obiect" pentru a urmări numărul de chei/proprietăți, deci nu ar fi nici o modalitate standard de a determina dimensiunea de un "Obiect" fără explicit sau implicit iterarea peste cheile sale.
Deci, aici sunt cele mai frecvent utilizate alternative:
1. ECMAScript's Obiect.tastele()
`Obiect.cheile(obj).lungime; Lucrări de intern iterarea peste cheile pentru a calcula o temporară matrice și returnează lungimea sa.
2. Biblioteca soluții bazate pe
Multe bibliotecă pe bază de exemple în altă parte în acest subiect sunt utile expresii în contextul lor bibliotecă. Dintr-un punct de vedere performanta, cu toate acestea, nu este nimic de a câștiga în comparație cu o perfectă nu-bibliotecă cod de toți cei biblioteca metodele de fapt îngloba fie un pentru buclă sau ES5
Obiect.chei
(nativ sau shimmed).3. Optimizarea o pentru buclă
La lent parte de o astfel de buclă este în general
.hasOwnProperty()
apel, pentru că de apelul funcției deasupra capului. Așa că atunci când vreau doar numărul de intrări de un obiect JSON, doar sari peste.hasOwnProperty () sun dacă am ști că nici un cod nu se va extinde
Obiect.prototip`.În caz contrar, codul ar putea fi foarte ușor optimizat prin a face " k " locale (
var k
) și prin utilizarea prefix-operatorul de incrementare (++conta
) în loc de postfix.O altă idee se bazează pe cache
hasOwnProperty
metoda:Dacă acest lucru este mai rapid sau nu pe un anumit mediu este o chestiune de benchmarking. Foarte limitate de creștere a performanței poate fi de așteptat oricum.
Dacă sunt, de fapt rula într-o problemă de performanță aș sugera ambalaj apelurile care se adăuga/elimina proprietăți de la/la obiect cu o funcție care, de asemenea, creșteri/diminuări de un nume adecvat (dimensiune?) proprietate.
Ai nevoie doar pentru a calcula numărul inițial de proprietăți odată și pentru a muta de acolo. Dacă nu există't o reală problemă de performanță, don't deranjez. Înfășurați doar că pic de cod într-o funcție `getNumberOfProperties(obiect) și să fie făcut cu ea.
Am'm nu are cunoștință de nicio modalitate de a face acest lucru, cu toate acestea, pentru a menține iterații la un nivel minim, ai putea încerca de verificare pentru existenta
__count__
și dacă nu't există (de exemplu, nu Firefox), atunci ai putea repeta peste obiect și-l definească pentru o utilizare ulterioară, de exemplu:În acest fel în orice browser-ul de sprijin
__count__
ar folosi asta, și iterații ar fi efectuate numai pentru cei care don't. În cazul în care numărul modificările și puteți't face acest lucru, ai putea face întotdeauna o funcție:În acest fel, oricand ai referință myobj.
__conta__
funcția va foc și se recalculează.După cum sa afirmat de Avi In https://stackoverflow.com/a/4889658/1047014
va face truc pentru toate nenumărate proprietăți pe obiect, ci să includă, de asemenea, non-nenumărate proprietăți puteți folosi în loc de
Obiect.getOwnPropertyNames
. Aici's diferența:După cum a afirmat aici acest lucru are același sprijin browser-ul ca
Obiect.tastele
Cu toate acestea, în cele mai multe cazuri, s-ar putea să nu doriți să includă nonenumerables în acest tip de operațiuni, dar's întotdeauna bine să știți diferența ;)
Pentru a repeta pe un Avi In răspundă la Obiect.cheile(obj).lungimea este corect pentru un obiect care nu are funcții legate de aceasta
exemplu:
versus
pași pentru a evita acest lucru:
nu pune funcții într-un obiect pe care doriți să conta numărul de chei în
utilizarea separată de obiect sau de a face un obiect nou special pentru funcții (dacă doriți să conta cât de multe funcții sunt în fișier folosind
Obiect.cheile(obj).lungimea
)de asemenea, da am folosit _ sau subliniere modul de nodejs în exemplul meu
documentație pot fi găsite aici http://underscorejs.org/ precum și ca sursă pe github și diverse alte informatii
Și în cele din urmă un lodash punerea în aplicare https://lodash.com/docs#size
_.dimensiune(obj)
ca raspuns mai sus:
Obiect.cheile(obj).lungime
Dar: ca avem acum o real Harta clasă în ES6, am ar arată să-l folosească în loc de a folosi proprietățile unui obiect.
Pentru cei care au Underscore.js incluse în proiectul lor le puteți face:
sau stil funcțional:
De la: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
Puteți fie să adăugați-l la toate obiectele:
Sau un singur obiect:
Exemplu:
A adăugat că va avea't fi afișate în for..în bucle:
Ieșire:
Notă: nu funcționează în < IE9 browsere.
Cum am'am rezolvat această problemă este de a construi propriul meu punerea în aplicare de o listă de bază care ține o evidență a cât de multe elemente sunt stocate în obiect. Este foarte simplu. Ceva de genul asta:
Puteți folosi Obiect.cheile(de date).lungime` pentru a găsi lungimea de obiect JSON având datele-cheie
Pentru cei care au Ext JS 4 în proiectul lor le puteți face:
Avantajul acestui fapt este că-l'll lucra pe toate Ext browsere compatibile (IE6-IE8 inclus), cu toate acestea, cred că timpul de funcționare este mai bună decât O(n), deși, ca și cu alte soluții sugerate.
OP n't specifica dacă obiectul este un nodeList, dacă este, atunci puteți folosi doar lungime metoda pe ea direct. Exemplu:
Dacă jQuery de mai sus nu funcționează, apoi încercați
Aici sunt unele teste de performanță pentru trei metode;
https://jsperf.com/get-the-number-of-keys-in-an-object
Obiect.tastele().lungime
20,735 operații pe secundă
Foarte simplu și compatibile. Se execută rapid but scumpe pentru că se creează o nouă serie de chei, care apoi este aruncat.
returnare Obiect.cheile(objectToRead).lungime;
bucla prin chei
15,734 operații pe secundă
să size=0; pentru(fie k în objectToRead) { dimensiunea++ } reveni dimensiune;
Ușor mai lent, dar nicăieri în apropiere de utilizare de memorie, deci probabil mai bine dacă te - 're interesat în optimizarea pentru mobil sau alte masini mici
Folosind Harta în loc de Obiect
953,839,338 operații pe secundă
reveni mapToRead.dimensiune;
Practic, Harta piese propria sa dimensiune atât de ne're întorcându-se doar o serie de teren. Mult, mult mai repede decât orice altă metodă. Dacă aveți de control al obiectului, de a le converti la hărți în loc.
Puteți utiliza:
și
Am încercat să-l facă disponibil pentru toți obiect de genul asta:
Eu nu't cred că acest lucru este posibil (cel puțin nu fără a utiliza unele interne). Și eu nu't cred că ar câștiga mult prin optimizarea acest lucru.