javascript-objects d'objet - Longueur d'un objet JavaScript




parcourir tableau (25)

Si j'ai un objet JavaScript, disons

var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;

Y a-t-il une méthode de meilleure pratique intégrée ou acceptée pour obtenir la longueur de cet objet?


Answers

Pour ne pas jouer avec le prototype ou un autre code, vous pouvez construire et étendre votre propre objet:

function Hash(){
    var length=0;
    this.add = function(key, val){
         if(this[key] == undefined)
         {
           length++;
         }
         this[key]=val;
    }; 
    this.length = function(){
        return length;
    };
}

myArray = new Hash();
myArray.add("lastname", "Simpson");
myArray.add("age", 21);
alert(myArray.length()); // will alert 2

Si vous utilisez toujours la méthode add, la propriété length sera correcte. Si vous craignez que vous ou d'autres ne l'utilisiez pas, vous pouvez également ajouter le compteur de propriétés que les autres ont également envoyé à la méthode length.

Bien sûr, vous pouvez toujours remplacer les méthodes. Mais même si vous le faites, votre code échouerait probablement sensiblement, ce qui le rendrait facile à déboguer. ;)


Qu'en est-il de quelque chose comme ça -

function keyValuePairs() {
    this.length = 0;
    function add(key, value) { this[key] = value; this.length++; }
    function remove(key) { if (this.hasOwnProperty(key)) { delete this[key]; this.length--; }}
}

Nous pouvons trouver la longueur de l'objet en utilisant:

Object.values(myObject).length

Si vous utilisez AngularJS 1.x, vous pouvez faire les choses de la manière AngularJS en créant un filtre et en utilisant le code de l'un des autres exemples suivants:

// Count the elements in an object
app.filter('lengthOfObject', function() {
  return function( obj ) {
    var size = 0, key;
    for (key in obj) {
      if (obj.hasOwnProperty(key)) size++;
    }
   return size;
 }
})

Usage

Dans votre contrôleur:

$scope.filterResult = $filter('lengthOfObject')($scope.object)

Ou à votre avis:

<any ng-expression="object | lengthOfObject"></any>

Solution simple:

  var myObject = {};      // ... your object goes here.

  var length = 0;

  for (var property in myObject) {
    if (myObject.hasOwnProperty(property)){
      length += 1;
    }
  };

  console.log(length);    // logs 0 in my example.

Voici la solution la plus cross-navigateur.

C'est mieux que la réponse acceptée car elle utilise des objets Object.keys natifs s'il existe. Ainsi, c'est le plus rapide pour tous les navigateurs modernes.

if (!Object.keys) {
    Object.keys = function (obj) {
        var arr = [],
            key;
        for (key in obj) {
            if (obj.hasOwnProperty(key)) {
                arr.push(key);
            }
        }
        return arr;
    };
}

Object.keys(obj).length;

Propriété

Object.defineProperty(Object.prototype, 'length', {
    get: function () {
        var size = 0, key;
        for (key in this)
            if (this.hasOwnProperty(key))
                size++;
        return size;
    }
});

Utilisation

var o = {a: 1, b: 2, c: 3};
alert(o.length); // <-- 3
o['foo'] = 123;
alert(o.length); // <-- 4

Utilisez quelque chose d'aussi simple que:

Object.keys(obj).length

Il ne doit pas être difficile et ne nécessite certainement pas une autre fonction à accomplir.


Dans certains cas, il est préférable de simplement stocker la taille dans une variable distincte. Surtout, si vous ajoutez au tableau par un élément à un endroit et pouvez facilement incrémenter la taille. Cela fonctionnerait évidemment beaucoup plus vite si vous devez vérifier la taille souvent.


Une variation sur certains de ce qui précède est:

var objLength = function(obj){    
    var key,len=0;
    for(key in obj){
        len += Number( obj.hasOwnProperty(key) );
    }
    return len;
};

C'est un moyen un peu plus élégant d'intégrer hasOwnProp.


Si nous avons le hash

hash = {"a": "b", "c": "d"};

nous pouvons obtenir la longueur en utilisant la longueur des clés qui est la longueur du hachage:

clés (hash) .length


Utilisation:

var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
obj = Object.keys(myArray).length;
console.log(obj)


Comme la plupart des problèmes JavaScript, il existe de nombreuses solutions. Vous pouvez étendre l'objet qui, pour le meilleur ou pour le pire, fonctionne comme le dictionnaire de beaucoup d'autres langues (+ citoyens de première classe). Rien de mal à cela, mais une autre option est de construire un nouvel objet qui répond à vos besoins spécifiques.

function uberject(obj){
    this._count = 0;
    for(var param in obj){
        this[param] = obj[param];
        this._count++;
    }
}

uberject.prototype.getLength = function(){
    return this._count;
};

var foo = new uberject({bar:123,baz:456});
alert(foo.getLength());

Cette méthode obtient tous les noms de propriété de votre objet dans un tableau, de sorte que vous pouvez obtenir la longueur de ce tableau qui est égale à la longueur des clés de votre objet.

Object.getOwnPropertyNames({"hi":"Hi","msg":"Message"}).length; // => 2

Si vous ne tenez pas compte de la prise en charge d'Internet Explorer 8 ou inférieur, vous pouvez facilement obtenir le nombre de propriétés dans un objet en appliquant les deux étapes suivantes:

  1. Exécutez developer.mozilla.org/en/docs/Web/JavaScript/Reference/… pour obtenir un tableau contenant uniquement les noms des propriétés enumerable ou Object.getOwnPropertyNames() si vous souhaitez également inclure les noms des propriétés qui ne sont pas énumérables.
  2. Récupère la propriété .length de ce tableau.

Si vous devez le faire plus d'une fois, vous pouvez intégrer cette logique dans une fonction:

function size(obj, enumerablesOnly) {
    return enumerablesOnly === false ?
        Object.getOwnPropertyNames(obj).length :
        Object.keys(obj).length;
}

Comment utiliser cette fonction particulière:

var myObj = Object.create({}, {
    getFoo: {},
    setFoo: {}
});
myObj.Foo = 12;

var myArr = [1,2,5,4,8,15];

console.log(size(myObj));        // Output : 1
console.log(size(myObj, true));  // Output : 1
console.log(size(myObj, false)); // Output : 3
console.log(size(myArr));        // Output : 6
console.log(size(myArr, true));  // Output : 6
console.log(size(myArr, false)); // Output : 7

Voyez aussi ce Fiddle pour une démo.


La réponse la plus robuste (c'est-à-dire qui capture l'intention de ce que vous essayez de faire en causant le moins de bogues) serait:

Object.size = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (obj.hasOwnProperty(key)) size++;
    }
    return size;
};

// Get the size of an object
var size = Object.size(myArray);

Il y a une sorte de convention dans JavaScript que vous n'ajoutez pas de choses à Object.prototype , car il peut casser des énumérations dans diverses bibliothèques. Ajout de méthodes à Object est généralement sûr, cependant.

Voici une mise à jour à partir de 2016 et un déploiement étendu de ES5 et au-delà. Pour IE9 + et tous les autres navigateurs modernes compatibles ES5 +, vous pouvez utiliser Object.keys() pour que le code ci-dessus devienne:

var size = Object.keys(myObj).length;

Cela n'a pas à modifier un prototype existant puisque Object.keys() est maintenant intégré.


@palmsey: En toute justice pour l'OP, les docs javascript se réfèrent explicitement à l'utilisation de variables de type Object de cette manière comme "tableaux associatifs".

Et en toute justice pour @palmsey, il avait tout à fait raison, ce ne sont pas des tableaux associatifs, ce sont définitivement des objets :) - faire le travail d'un tableau associatif. Mais en ce qui concerne le point plus large, vous semblez en avoir le droit, d'après ce très bon article que j'ai trouvé:

JavaScript "Arrays associatifs" considérés comme nuisibles

Mais selon tout cela, la réponse acceptée n'est-elle pas elle-même une mauvaise pratique?

Spécifiez une fonction prototype size () pour l'objet

Si quelque chose d'autre a été ajouté à Object .prototype, le code suggéré échouera:

<script type="text/javascript">
Object.prototype.size = function () {
  var len = this.length ? --this.length : -1;
    for (var k in this)
      len++;
  return len;
}
Object.prototype.size2 = function () {
  var len = this.length ? --this.length : -1;
    for (var k in this)
      len++;
  return len;
}
var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
alert("age is " + myArray["age"]);
alert("length is " + myArray.size());
</script>

Je ne pense pas que cette réponse devrait être acceptée car elle ne peut pas être fiable si vous avez un autre code exécuté dans le même contexte d'exécution. Pour le faire de manière robuste, vous devrez certainement définir la méthode size dans myArray et vérifier le type des membres au fur et à mesure que vous les parcourez.


Utilisez simplement ceci pour obtenir la length :

Object.keys(myObject).length

var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
  1. Object.values ​​(myObject) .length
  2. Object.entries (myObject) .length
  3. Object.keys (myObject) .length

Vous pouvez toujours faire Object.getOwnPropertyNames(myObject).length pour obtenir le même résultat que [].length donnerait pour le tableau normal.


Vous pouvez simplement utiliser Object.keys(obj).length sur n'importe quel objet pour obtenir sa longueur. Object.keys renvoie un tableau contenant toutes les clés d' objet (propriétés) qui peuvent être utiles pour trouver la longueur de cet objet en utilisant la longueur du tableau correspondant. Vous pouvez même écrire une fonction pour cela. Soyons créatifs et écrivons une méthode pour cela (avec une propriété getter plus pratique):

function objLength(obj)
{
  return Object.keys(obj).length;
}

console.log(objLength({a:1, b:"summit", c:"nonsense"}));

// Works perfectly fine
var obj = new Object();
obj['fish'] = 30;
obj['nullified content'] = null;
console.log(objLength(obj));

// It also works your way, which is creating it using the Object constructor
Object.prototype.getLength = function() {
   return Object.keys(this).length;
}
console.log(obj.getLength());

// You can also write it as a method, which is more efficient as done so above

Object.defineProperty(Object.prototype, "length", {get:function(){
    return Object.keys(this).length;
}});
console.log(obj.length);

// probably the most effictive approach is done so and demonstrated above which sets a getter property called "length" for objects which returns the equivalent value of getLength(this) or this.getLength()


Voici une version de la réponse de James Coglan dans CoffeeScript pour ceux qui ont abandonné JavaScript directement :)

Object.size = (obj) ->
  size = 0
  size++ for own key of obj
  size

Un peu en retard au jeu, mais une bonne façon d'y parvenir (IE9 + uniquement) est de définir un getter magique sur la propriété length:

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

Et vous pouvez juste l'utiliser comme ça:

var myObj = { 'key': 'value' };
myObj.length;

Donnerait 1 .


Voici une solution complètement différente qui ne fonctionnera que dans les navigateurs plus modernes (IE9 +, Chrome, Firefox 4+, Opera 11.60+, Safari 5.1+)

Voir jsFiddle

Configurez votre classe Array associative

/**
 * @constructor
 */
AssociativeArray = function () {};

// Make the length property work
Object.defineProperty(AssociativeArray.prototype, "length", {
    get: function () {
        var count = 0;
        for (var key in this) {
            if (this.hasOwnProperty(key))
                count++;
        }
        return count;
    }
});

Maintenant, vous pouvez utiliser ce code comme suit ...

var a1 = new AssociativeArray();
a1["prop1"] = "test";
a1["prop2"] = 1234;
a1["prop3"] = "something else";
alert("Length of array is " + a1.length);

Si vous voulez un nouveau tableau avec les positions supprimées supprimées, vous pouvez toujours supprimer l'élément spécifique et filtrer le tableau. Cela peut nécessiter une extension de l' objet tableau pour les navigateurs qui n'implémentent pas la méthode de filtrage, mais à plus long terme, c'est plus facile car tout ce que vous faites est la suivante:

var my_array = [1,2,3,4,5,6];
delete my_array[4];
console.log(my_array.filter(function(a){return typeof a !== 'undefined';}));

Doit-on afficher [1, 2, 3, 4, 6]





javascript javascript-objects