La façon la plus efficace de compter le nombre de touches/propriétés d'un objet en JavaScript?
Quel est le moyen le plus rapide pour compter le nombre de touches/propriétés d'un objet? Est-il possible de le faire sans une itération sur l'objet? c'est à dire sans faire
var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) count++;
(Firefox a fourni une magie __count__
bien, mais cela a été supprimé quelque part autour de la version 4.)
- Connexes: stackoverflow.com/questions/5223/...
- référence du rendement pour les différentes façons: jsben.ch/#/oSt2p
- Double Possible de la Longueur d'un objet JavaScript
Vous devez vous connecter pour publier un commentaire.
Pour ce faire, dans toute ES5-compatible environnement, comme Nœud, Chrome, IE 9+, Firefox 4+, Safari 5+:
var o = {a: 1, b: 2}; Object.keys(o).slice(1)
n'affecte pas l'o. Je ne pense pas qu'il y est une meilleure solution que ce que!map.keys()
refléter les modifications apportées àmap
après la.keys()
appel?Object.keys()
méthode, indépendamment de ce qui est "normal". En soulignant comment Java fait quelque chose n'a pas d'incidence sur cette conversation.Vous pouvez utiliser ce code:
Ensuite, vous pouvez l'utiliser dans les navigateurs plus anciens ainsi:
(Object.prototype.hasOwnProperty.call(obj, k))
?hasOwnProperty
est nécessaire. Il retourne uniquement des propriétés sur l'objet lui-même.call
surhasOwnProperty
au lieu de simplement en utilisantObject.prototype.hasOwnProperty(obj, k)
. Quel est le but de tout cela?obj.hasOwnProperty(k)
(je l'ai fait dans mon post original, mais mis à jour plus tard).hasOwnProperty
est disponible sur chaque objet, car il fait partie de laObject
s'prototype, mais dans les rares cas où cette méthode pourrait être supprimé ou remplacé, vous pouvez obtenir des résultats inattendus. En appelant à partir deObject.prototype
, elle la rend peu plus robuste. La raison de l'utilisationcall
est parce que vous voulez appeler la méthode surobj
au lieu de sur le prototype.Object.keys
est maintenant un standard fr doit être mis en œuvre dans les plus anciennes du navigateur de cette manière. Je vous propose de lire attentivement une fois de plus avant de commentaire sur ce nouveau...Si vous utilisez Underscore.js vous pouvez utiliser _.taille (merci @douwe):
_.size(obj)
Alternativement, vous pouvez également utiliser _.touches qui peut être plus clair pour certains:
_.keys(obj).length
Je recommande fortement le trait de Soulignement, son serrée de la bibliothèque pour faire beaucoup de choses de base. Chaque fois que possible, s'ils correspondent ECMA5 et de reporter à l'implémentation native.
Sinon je soutiens @Avi réponse. J'ai édité pour ajouter un lien vers les MDC doc qui comprend la méthode keys() vous pouvez ajouter à la non-ECMA5 navigateurs.
_.keys(obj).length
fonctionne le mieux pour moi, parce que mon objet de retour est parfois une simple chaîne à aucune des propriétés à l'intérieur._.size(obj)
me donne de nouveau la longueur de la chaîne, tandis que_.keys(obj).length
retourne 0.Object.keys
en interne. Soulignent également des copies de toutes les clés dans un tableau à l'intérieur d'unfor..in
boucle siObject.keys
n'est pas défini.La norme de l'Objet de la mise en œuvre (ES5.1 Objet Interne Propriétés et Méthodes) ne nécessite pas de
Object
pour suivre son nombre de touches/propriétés, il devrait donc y avoir aucun moyen standard pour déterminer la taille d'unObject
sans explicitement ou implicitement une itération sur ses touches.Donc, ici, sont les plus couramment utilisés alternatives:
1. ECMAScript de l'Objet.les touches()
Object.keys(obj).length;
Œuvres par en interne itération sur les touches pour calculer un tableau temporaire et retourne sa longueur.2. Bibliothèque de solutions à base d'
De nombreux bibliothèque basée sur des exemples ailleurs dans cette rubrique sont utiles idiomes dans le contexte de leur bibliothèque. À partir d'un point de vue des performances, cependant, il n'y a rien à gagner par rapport à un idéal de non-bibliothèque de code, puisque tous ceux de la bibliothèque de méthodes d'encapsuler une boucle for ou ES5
Object.keys
(natif ou calée).3. L'optimisation d'une boucle for
La plus lente d'une telle boucle for est généralement le
.hasOwnProperty()
appel, en raison de l'appel de la fonction de surcharge. Donc quand je veux juste le nombre d'entrées d'un objet JSON, je viens de sauter le.hasOwnProperty()
appeler si je sais qu'aucun code n'a ni la volonté d'étendreObject.prototype
.Sinon, votre code pourrait être très légèrement optimisé en faisant
k
local (var k
) et en utilisant le préfixe-opérateur d'incrémentation (++count
) au lieu de postfix.Une autre idée s'appuie sur la mise en cache de la
hasOwnProperty
méthode:Si c'est plus rapide ou pas sur un environnement donné est une question de benchmarking. Très limitée gain de performance peut être prévu de toute façon.
var k in myobj
de booster les performances? Autant que je sache, seules les fonctions de déclarer le nouveau champ d'application en JavaScript. Sont-boucles une exception à cette règle?for (var k in myobj) hasOwn.call(myobj, k) && ++count;
c'est à dire le remplacement de l'instruction si avec un simple &&?Si vous sont effectivement en cours d'exécution dans un problème de performance, je voudrais suggérer d'emballage les appels que ajouter/supprimer des propriétés à/à partir de l'objet avec une fonction aussi incrémente/décrémente un bien nommé (taille?) de la propriété.
Vous avez seulement besoin de calculer le nombre initial de propriétés une fois et de passer à partir de là. Si il n'y a pas un réel problème de performance, n'est pas la peine. Juste envelopper ce bout de code dans une fonction
getNumberOfProperties(object)
et être fait avec elle.Je ne suis pas au courant de toute façon pour ce faire, cependant, de garder les itérations à un minimum, vous pouvez essayer de vérifier l'existence de
__count__
et si elle n'existe pas (c'est à dire pas Firefox) puis vous pouvez effectuer une itération sur l'objet et la définition pour une utilisation ultérieure, par exemple:De cette façon, tout navigateur supportant
__count__
permettrait de l'utiliser, et les itérations ne seraient menées pour ceux qui ne le sont pas. Si le nombre de changements et vous ne pouvez pas faire cela, vous pouvez toujours faire une fonction:De cette façon, quand vous faites référence à myobj.
__count__
la fonction d'incendie et de recalculer.Object.prototype.__count__
est retiré dans Gecko 1.9.3: whereswalden.com/2010/04/06/...count-bien-des-objets-est-supprimé/Object.__count__
est parti, et bon débarras trop.Comme l'a déclaré Avi Lin https://stackoverflow.com/a/4889658/1047014
va faire le tour de toutes les propriétés énumérables sur votre objet mais également à la non-énumérable propriétés que vous pouvez utiliser à la place la
Object.getOwnPropertyNames
. Voici la différence:Comme indiqué ici cela a le même support de navigateur comme
Object.keys
Cependant, dans la plupart des cas, vous risquez de ne pas inclure les nonenumerables dans ce type d'opérations, mais il est toujours bon de connaître la différence 😉
Pour itérer sur Avi Lin réponse de l'Objet.les touches(obj).la longueur est correcte pour un objet qui n'a pas les fonctions d'attaché
exemple:
contre
des mesures pour éviter cela:
ne pas mettre les fonctions dans un objet que vous souhaitez compter le nombre de clés dans
utiliser un objet séparé ou créer un nouvel objet spécifiquement pour les fonctions (si vous voulez compter le nombre de fonctions il y a dans le fichier à l'aide de
Object.keys(obj).length
)aussi oui j'ai utilisé l' _ ou un trait de soulignement module nodejs dans mon exemple
documentation peut être trouvée ici http://underscorejs.org/ ainsi que sa source sur github et diverses autres informations
Et enfin un lodash mise en œuvre https://lodash.com/docs#size
_.size(obj)
Array(obj).length
: Il ne fonctionne pas. http://jsfiddle.net/Jhy8M/false
, bien que je n'ai pas encore trouvé aucune documentation sur commentvar obj = { a: true, b: true }
peut différer devar obj = {}; obj.a = true; obj.b = true;
ou tout simplement si une autre interprétation sémantique de la W3 a été adopté par le Chrome.Pour ceux qui ont Underscore.js inclus dans leur projet que vous pouvez faire:
ou fonctionnelle style:
À partir de: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
Vous pouvez ajouter tous vos objets:
Ou à un objet unique:
Exemple:
Ajoutée de cette façon, il ne sera pas affiché dans les boucles for..in:
De sortie:
Remarque: il ne fonctionne pas dans < IE9 navigateurs.
comme répondu plus haut:
Object.keys(obj).length
Mais: comme nous l'avons maintenant un véritable Carte classe dans l'ES6, je suggérer de l'utiliser au lieu d'utiliser les propriétés d'un objet.
Comment j'ai résolu ce problème est de construire ma propre mise en œuvre d'une liste de base qui conserve une trace de la façon dont de nombreux éléments sont stockés dans l'objet. Elle est très simple. Quelque chose comme ceci:
var i = basiclist.count
while(i--){...}
add
remplace un ancien élément ou, siremove
est appelée avec un non-index existant. Aussi il n'est pas possible de vérifier si la liste a un index donné siundefined
est un élément valide de valeur.get
ontif (undefined === index)
? Comme c'est le test est inversée et utiliser uneundefined
index pour accéder au tableau.Pour ceux qui ont Ext JS 4 dans leur projet que vous pouvez faire:
L'avantage, c'est que cela marche sur tous les Ext compatible navigateurs (IE6-IE8 inclus), cependant, je crois que le temps d'exécution n'est pas meilleure que O(n), bien que, comme avec les autres solutions proposées.
Vous pouvez utiliser
Object.keys(data).length
pour trouver la longueur de l'objet JSON avoir des données clésSi jQuery ci-dessus ne fonctionne pas, alors essayez de
Object.Item
n'existe pasOP n'a pas préciser si l'objet est une nodeList, si elle est, alors vous pouvez simplement utiliser longueur méthode directement. Exemple:
Je ne pense pas que ce soit possible, du moins pas sans l'aide de certains éléments internes). Et je ne pense pas que l'on gagnerait beaucoup en optimisant ce.
J'essaie de la rendre accessible à tous un objet comme ça:
Google Fermeture a une belle fonction pour cette... goog.objet.getCount(obj)
regardez goog.Objet De La Documentation
Vous pouvez utiliser:
Object.keys(objectName).length;
& Object.values(objectName).length;