2010-07-01 2 views
9

J'ai un objet Javascript que j'essaie d'utiliser comme un "hashmap". Les clés sont toujours des chaînes, donc je ne pense pas avoir besoin de quelque chose d'aussi sophistiqué que ce qui est décrit dans this SO question. (Je ne m'attends pas non plus à ce que le nombre de clés dépasse 10, donc je ne suis pas particulièrement concerné par les recherches O (n) vs. O (log n) etc.)Déterminer combien de champs un objet Javascript a

La seule fonctionnalité que je veux les objets Javascript intégrés ne semblent pas avoir, est un moyen rapide de comprendre le nombre de paires clé/valeur dans l'objet, comme ce que Map.size de Java renvoie. Bien sûr, vous pouvez simplement faire quelque chose comme:

function getObjectSize(myObject) { 
    var count=0 
    for (var key in myObject) 
    count++ 
    return count 
} 

mais qui semble un peu hacky et rond-point. Y a-t-il une "bonne façon" d'obtenir le nombre de champs dans l'objet?

+0

La seule suggestion à votre méthode serait d'ajouter un paramètre supplémentaire à exclure/inclure les propriétés héritées, dans ce cas, vous utilisez hasOwnProperty au lieu de simplement la boucle simple –

Répondre

3

Une correction: vous devez vérifier myObject.hasOwnProperty(key) à chaque itération, car il peut y avoir des attributs hérités. Par exemple, si vous faites cela avant la boucle Object.prototype.test = 'test', test sera également compté.

Et en parlant de votre question: vous pouvez simplement définir une fonction d'aide, si la vitesse n'a pas d'importance. Après tout, nous définissons des aides pour la fonction d'assiette et d'autres choses simples. Beaucoup de javascript est « type de aki et rond-point » :)

mise à jour
défaut par exemple, comme l'a demandé.

Object.prototype.test = 'test'; 
var x = {}; 
x['a'] = 1; 
x['b'] = 2; 

Le nombre retourné sera 3.

+0

L'objet est créé avec 'myObject = {}' et les propriétés sont ajoutées avec 'myObject [clé] = valeur' où' clé' est toujours une chaîne. Je pense donc que ce ne serait pas une préoccupation dans ce cas. – MatrixFrog

+0

@MatrixFrog Oh, vraiment? :) Peu importe quel type est «clé». J'ai ajouté un exemple pour clarifier le point. –

+0

btw, Anurag appuie sur le même point dans sa réponse (le commentaire là-bas) –

0

vous pouvez aussi faire juste myObject.length (dans les tableaux)

Nevermind, voir ceci: JavaScript object size

+1

Il ne pose pas de questions sur les tableaux, ni sur un 'sizeof'. Il veut le nombre de mappages (paires clé-valeur) dans un objet. –

+0

'myObject.longueur »a été ma première pensée, mais oui, cela ne fonctionne que pour les tableaux. – MatrixFrog

+0

BTW, le lien que vous donnez est pour SIZEOF, par exemple. nombre d'octets utilisés. OP veut connaître le nombre de paires clé-valeur dans un objet. (J'ai presque fait -1 parce que ce n'est pas une réponse à la question, mais le lien est intéressant, même si sur un sujet différent.) – ToolmakerSteve

0

C'est tout ce que vous pouvez faire. Clairement, les objets JavaScript ne sont pas conçus pour cela. Et cela ne vous donnera que le nombre de propriétés Enumerable. Essayez getObjectSize(Math).

13

Il y a un moyen plus facile à ECMAScript 5. spec'd

Object.keys(..) retourne un tableau de toutes les clés définies sur l'objet. La longueur peut être appelée là-dessus. Essayez Chrome:

Object.keys({a: 1, b: 2}).length; // 2 

Notez que tous les objets sont essentiellement des paires clé/valeur en JavaScript, et ils sont aussi très extensible. Vous pouvez étendre le Object.prototype avec une méthode size et obtenir le compte là. Cependant, une meilleure solution est de créer une interface de type HashMap ou d'utiliser l'une des nombreuses implémentations existantes, et de définir size dessus. Voici une petite mise en œuvre:

function HashMap() {} 

HashMap.prototype.put = function(key, value) { 
    this[key] = value; 
}; 

HashMap.prototype.get = function(key) { 
    if(typeof this[key] == 'undefined') { 
     throw new ReferenceError("key is undefined"); 
    } 
    return this[key]; 
}; 

HashMap.prototype.size = function() { 
    var count = 0; 

    for(var prop in this) { 
     // hasOwnProperty check is important because 
     // we don't want to count properties on the prototype chain 
     // such as "get", "put", "size", or others. 
     if(this.hasOwnProperty(prop) { 
      count++; 
     } 
    } 

    return count; 
}; 

Utilisation comme (example):

var map = new HashMap(); 
map.put(someKey, someValue); 
map.size(); 
+0

ne renvoient que les clés Enumerable, hasOwnProperty. –

+0

"TypeError: Object.keys n'est pas une fonction". J'imagine que j'aurais dû mentionner que je travaillais sur une extension Firefox, donc si ça ne marche pas dans Firefox alors c'est plutôt inutile pour moi. Toujours, bonne information pour l'avenir. Merci! – MatrixFrog

+0

@Matthew - oui, c'est pourquoi j'ai dit * défini sur l'objet * et oui l'énumérabilité est importante aussi, mais c'est ce que 'for..in' va revenir aussi, donc je l'ai laissé hors de la discussion. @MatrixFrog - Cela devrait venir dans Firefox 4, et vous pouvez toujours définir un type d'objet personnalisé avec une méthode de taille, comme dans l'exemple ci-dessus. – Anurag

Questions connexes