Kaip efektyviai skaičiuoti „JavaScript“ objektų raktų / savybių skaičių?

Kas yra greičiausias būdas apskaičiuoti objekto raktų / savybių skaičių? Ar tai galima padaryti be iteracijos per objektą? t.y. be atlikimo

 var count = 0; for (k in myobj) if (myobj.hasOwnProperty(k)) count++; 

(„Firefox“ suteikė magišką __count__ nuosavybę, tačiau ji buvo pašalinta kažkur aplink 4 versiją.)

1232
24 сент. nustatė mjs 24 sep . 2008-09-24 11:56 '08 at 11:56 2008-09-24 11:56
@ 19 atsakymų

Norėdami tai padaryti bet kurioje ES5 suderinamoje aplinkoje, pvz., „ Node“ , „Chrome“, „IE 9+“, „FF 4+“ arba „Safari 5+“:

Naršyklės suderinamumas 
  • Dokumentacijos objektas.pavyzdžiai
    • (apima metodą, kurį galite pridėti prie ne ECMA5 naršyklės)
  • 2046 m
    03 февр. Avi linai paskelbti vasario 03 d 2011-02-03 20:47 '11 prie 20:47 2011-02-03 20:47

    Galite naudoti šį kodą:

     if (!Object.keys) { Object.keys = function (obj) { var keys = [], k; for (k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) { keys.push(k); } } return keys; }; } 
    border=0

    Tada galite ją naudoti senesnėse naršyklėse:

     var len = Object.keys(obj).length; 
    142
    15 апр. Renaat De Muynck atsakymas, pateiktas balandžio 15 d 2011-04-15 13:48 '11, 13:48, 2011-04-15 13:48

    Jei naudojate „ Underscore.js“ , galite naudoti _. dydis (dėka @douwe):
    _.size(obj)

    Taip pat galite naudoti _. raktai , kurie gali būti aiškesni:
    _.keys(obj).length

    Aš labai rekomenduoju „Underscore“, jos tankią biblioteką, kad galėtume atlikti daug pagrindinių dalykų. Jei įmanoma, jie atitinka ECMA5 reikalavimus ir nurodo pradinį įgyvendinimą.

    Priešingu atveju pritariu atsakymui @Avi. Redagavau, kad pridėjau nuorodą į MDC dokumentą, kuriame yra raktų () metodas, kurį galite pridėti prie ne ECMA5 naršyklės.

    128
    16 мая '11 в 18:24 2011-05-16 18:24 Klausytojo atsakymas gegužės 16 d., 11 val. 18:24 2011-05-16 18:24

    Standartinis objekto įgyvendinimas ( ES5.1 objekto vidinės savybės ir metodai ) nereikalauja Object stebėti savo raktų / savybių skaičių, todėl neturėtų būti standartinis būdas nustatyti objekto dydį be aiškios ar netiesioginės iteracijos per savo raktus,

    Taigi, čia yra dažniausiai naudojamos alternatyvos:

    1. ECMAScript Object.keys ()

    Object.keys(obj).length; Atlieka vidinį kartojimą per klavišus, kad apskaičiuotų laikiną masyvą ir grąžintų jo ilgį.

    • Pliusai - nuskaitoma ir švari sintaksė. Nereikalaujama jokios bibliotekos ar pasirinktinio kodo, išskyrus padėklą, jei nėra vietinės paramos.
    • Suvart - atminties išlaidos dėl masyvo sukūrimo.

    2. Bibliotekos sprendimai

    Daugelis pavyzdžių, paremtų bibliotekoje kitur šiame skyriuje, yra naudingi jų bibliotekos kontekste. Vis dėlto, veikimo požiūriu, nėra nieko, ką galima palyginti su tobulu kodu be bibliotekos, nes visi šie bibliotekos metodai faktiškai apima „ Object.keys klavišą „loop“ objektams arba „ Object.keys (gimtoji arba shimmed).

    3. Kontūro kilpos optimizavimas

    .hasOwnProperty() tokios grandinės dalis, kaip taisyklė, yra .hasOwnProperty() skambutis .hasOwnProperty() dėl funkcijų skambučio paslaugų duomenų. Taigi, kai man reikia tik JSON objektų įrašų skaičiaus, aš tiesiog praleidžiu .hasOwnProperty() jei žinau, kad nė vienas kodas .hasOwnProperty() Object.prototype .

    Priešingu atveju, jūsų kodas gali būti šiek tiek optimizuotas padarant k vietinį ( var k ) ir naudodami prieaugio prefikso operatorių ( ++count ) vietoj postfix.

     var count = 0; for (var k in myobj) if (myobj.hasOwnProperty(k)) ++count; 

    Kita idėja yra pagrįsta „ hasOwnProperty metodo spartinimu:

     var hasOwn = Object.prototype.hasOwnProperty; var count = 0; for (var k in myobj) if (hasOwn.call(myobj, k)) ++count; 

    Nesvarbu, ar tai greitesnė, ar ne šioje aplinkoje, yra lyginamosios analizės klausimas. Bet kuriuo atveju galima tikėtis labai riboto našumo padidėjimo.

    66
    27 мая '13 в 0:39 2013-05-27 00:39 atsakymą pateikė Luc125 27 gegužės 13 d. 0:39 2013-05-27 00:39

    Jei iš tikrųjų susiduriate su našumo problema, siūlau įvesti skambučius, kurie prideda / pašalina savybes į objektą / objektą, naudodami funkciją, kuri taip pat padidina / mažina nuosavybę su atitinkamu pavadinimu (dydis?).

    Jums reikia tik apskaičiuoti pradinį savybių skaičių ir eiti iš ten. Jei nėra jokių veikimo problemų, nesijaudinkite. Tiesiog getNumberOfProperties(object) šį kodo getNumberOfProperties(object) į getNumberOfProperties(object) funkciją ir atlikite su juo.

    23
    24 сент. atsakymas pateikiamas „ Confusion“ rugsėjo 24 d 2008-09-24 12:11 '08 12:11 pm 2008-09-24 12:11

    Kaip nurodyta Avi linai ngn-wiki.ru.site/questions/10792 / ...

     Object.keys(obj).length 

    atliks visų objektų visų išvardintų savybių gudrybę, bet taip pat apima Object.getOwnPropertyNames ypatybes, kurias galite naudoti Object.getOwnPropertyNames . Čia yra skirtumas:

     var myObject = new Object(); Object.defineProperty(myObject, "nonEnumerableProp", { enumerable: false }); Object.defineProperty(myObject, "enumerableProp", { enumerable: true }); console.log(Object.getOwnPropertyNames(myObject).length); //outputs 2 console.log(Object.keys(myObject).length); //outputs 1 console.log(myObject.hasOwnProperty("nonEnumerableProp")); //outputs true console.log(myObject.hasOwnProperty("enumerableProp")); //outputs true console.log("nonEnumerableProp" in myObject); //outputs true console.log("enumerableProp" in myObject); //outputs true 

    Kaip nurodyta čia, ji turi tą patį naršyklės palaikymą kaip Object.keys

    Vis dėlto daugeliu atvejų negalėsite įtraukti nenumerinių numerių į šią operacijos rūšį, tačiau visada naudinga žinoti skirtumą;)

    15
    17 янв. Atsakymą pateikia BenderTheOffender, sausio 17 d 2013-01-17 14:15 '13, 14:15, 2013-01-17 14:15

    Nežinau, kaip tai padaryti, tačiau, norint sumažinti iteracijas, galite pabandyti patikrinti __count__ egzistavimą, o jei neegzistuoja (tai yra ne „Firefox“), galite pakartoti objektą ir nustatyti jį vėlesniam naudojimui, pavyzdžiui:

     if (myobj.__count__ === undefined) { myobj.__count__ = ... } 

    Taigi, bet kokia naršyklė, palaikanti __count__ bus naudojama, o iteracijos bus atliekamos tik tiems, kurie to nedaro. Jei skaitiklis pasikeičia ir negalite to padaryti, visada galite padaryti jį funkcija:

     if (myobj.__count__ === undefined) { myobj.__count__ = function() { return ... } myobj.__count__.toString = function() { return this(); } } 

    Tokiu būdu bet kuriuo metu kreipkitės į myobj. __count__ funkcija bus įjungta ir perskaičiuota.

    15
    24 сент. atsakymas, kurį pateikė Luke Bennett rugsėjo 24 d 2008-09-24 12:13 '08, 12:13 2008-09-24 12:13

    Avi Flax Object.keys (obj) .length atsako iteracija tinka objektui, kuriame nėra susijusių funkcijų

    Pavyzdys:

     obj = {"lol": "what", owo: "pfft"}; Object.keys(obj).length; // should be 2 

    prieš

     arr = []; obj = {"lol": "what", owo: "pfft"}; obj.omg = function(){ _.each(obj, function(a){ arr.push(a); }); }; Object.keys(obj).length; // should be 3 because it looks like this  

    to išvengti:

    • nedėkite funkcijų į objektą, į kurį norite suskaičiuoti raktų skaičių

    • naudokite atskirą objektą arba sukurkite naują objektą specialiai funkcijoms (jei norite apskaičiuoti, kiek funkcijų yra faile naudojant Object.keys(obj).length )

    Taip pat, mano pavyzdyje naudodavau „nodejs“ _ arba pabraukimo modulį

    Dokumentaciją galima rasti čia http://underscorejs.org/ , taip pat jos šaltinį „github“ ir kitą informaciją.

    Ir galiausiai, „lodash https://lodash.com/docs#size“ įgyvendinimas

    _.size(obj)

    12
    30 марта '14 в 4:11 2014-03-30 04:11 atsakymą pateikė Belldandu kovo 14 d. 14 d. 4:11 2014-03-30 04:11

    Tiems, kurie turi Underscore.js įtrauktus į savo projektą, galite:

     _.size({a:'', b:''}) // => 2 
    8
    04 янв. atsakymas pateikiamas hakunin 04 jan. 2012-01-04 12:04 '12 12:04 2012-01-04 12:04

    Nuo: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

    Object.defineProperty (obj, prop, deskriptorius)

    Galite jį pridėti prie visų objektų:

     Object.defineProperty(Object.prototype, "length", { enumerable: false, get: function() { return Object.keys(this).length; } }); 

    Arba vienas objektas:

     var myObj = {}; Object.defineProperty(myObj, "length", { enumerable: false, get: function() { return Object.keys(this).length; } }); 

    Pavyzdys:

     var myObj = {}; myObj.name = "John Doe"; myObj.email = "leaked@example.com"; myObj.length; //output: 2 

    Tokiu būdu ji nebus rodoma „for.in“ kilpose:

     for(var i in myObj) { console.log(i + ":" + myObj[i]); } 

    Išvada:

     name:John Doe email:leaked@example.com 

    Pastaba: jis neveikia <IE9.

    6
    21 авг. atsakymas duotas lepe 21 rug . 2015-08-21 06:37 '15 at 6:37 am 2015-08-21 06:37

    Kaip išsprendžiau šią problemą - sukurkite savo pagrindinio sąrašo įgyvendinimą, kuriame saugoma, kiek objektų yra saugomi. Tai labai paprasta. Kažkas panašaus:

     function BasicList() { var items = {}; this.count = 0; this.add = function(index, item) { items[index] = item; this.count++; } this.remove = function (index) { delete items[index]; this.count--; } this.get = function(index) { if (undefined === index) return items; else return items[index]; } } 
    5
    28 июня '11 в 13:04 2011-06-28 13:04 atsakymas pateikiamas Spustelėkite „Upvote“ birželio 28 d. 11 val. 13:04 2011-06-28 13:04

    Tiems, kurie savo projekte turi „Ext JS 4“, galite:

     Ext.Object.getSize(myobj); 

    To privalumas yra tas, kad jis veiks visose interneto suderinamose naršyklėse (įskaitant IE6-IE8), tačiau manau, kad veikimo laikas nėra geresnis nei O (n), nors, kaip ir kitų siūlomų sprendimų atveju.

    3
    12 апр. Mark Rhodes atsakymas, pateiktas balandžio 12 d 2012-04-12 10:40 '12 10:40 2012-04-12 10:40

    kaip buvo Object.keys(obj).length Object.keys(obj).length aukščiau: Object.keys(obj).length

    Tačiau: kadangi dabar ES6 yra tikroji žemėlapių klasė, siūlau jį naudoti vietoj objekto savybių.

     const map = new Map(); map.set("key", "value"); map.size; // THE fastest way 
    2
    19 янв. Flavien Volken atsakymas, pateiktas sausio 19 d 2018-01-19 12:04 '18, 12:04 val. 2018-01-19 12:04

    Jei jQuery aukščiau neveikia, pabandykite

     $(Object.Item).length 
    1
    02 сент. atsakymas, suteiktas kodų kodą 02 rugsėjis. 2012-09-02 04:32 '12 at 4:32 2012-09-02 04:32

    Nemanau, kad tai įmanoma (bent jau ne naudojant kai kuriuos vidinius komponentus). Ir nemanau, kad laimėsite optimizuodami.

    1
    24 сент. atsakymas pateikiamas rugsėjo 24 d 2008-09-24 12:05 '08 12:05 val. 2008-09-24 12:05

    Galite naudoti Object.keys(data).length kad rastumėte JSON objekto ilgį su pagrindiniais duomenimis.

    0
    10 июля '18 в 11:26 2018-07-10 11:26 atsakymą pateikė Codemaker, liepos 10 d., 18 val., 11:26, 2018-07-10 11:26

    Bandau padaryti jį prieinamą visiems objektams taip:

     Object.defineProperty(Object.prototype, "length", { get() { if (!Object.keys) { Object.keys = function (obj) { var keys = [],k; for (k in obj) { if (Object.prototype.hasOwnProperty.call(obj, k)) { keys.push(k); } } return keys; }; } return Object.keys(this).length; },}); console.log({"Name":"Joe","Age":26}.length) //returns 2 
    0
    14 апр. Atsakymas, kurį pateikė Taquate 14 Bal. 2018-04-14 15:51 '18, 15:51 2018-14-14 15:51

    Galite naudoti: Object.keys(objectName).length; Object.values(objectName).length; Object.keys(objectName).length; Object.values(objectName).length; Object.keys(objectName).length; Object.values(objectName).length;

    -1
    28 февр. Atsakymą pateikė Fayaz 28 vasario mėn. 2018-02-28 10:09 '18, 10:09 pm 2018-02-28 10:09

    „Google“ uždarymas turi gerą funkciją šiam tikslui ... goog.object.getCount (obj)

    žr. „goog

    -1
    13 дек. Sebastiano Perezio atsakymas, gruodžio 13 d 2011-12-13 17:04 '11, 5:04 val. 2011-12-13 17:04