objetos - recorrer objeto json javascript
¿Cómo contar de manera eficiente el número de claves/propiedades de un objeto en JavaScript? (13)
De: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
Object.defineProperty (obj, prop, descriptor)
Puedes agregarlo a todos tus objetos:
Object.defineProperty(Object.prototype, "length", {
enumerable: false,
get: function() {
return Object.keys(this).length;
}
});
O un solo objeto:
var myObj = {};
Object.defineProperty(myObj, "length", {
enumerable: false,
get: function() {
return Object.keys(this).length;
}
});
Ejemplo:
var myObj = {};
myObj.name = "John Doe";
myObj.email = "[email protected]";
myObj.length; //output: 2
Agregado de esa manera, no se mostrará en for..in loops:
for(var i in myObj) {
console.log(i + ":" + myObj[i]);
}
Salida:
name:John Doe
email:[email protected]
Nota: no funciona en <navegadores IE9.
¿Cuál es la forma más rápida de contar el número de claves / propiedades de un objeto? ¿Es posible hacer esto sin iterar sobre el objeto? es decir, sin hacer
var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) count++;
(Firefox proporcionó una propiedad mágica __count__
, pero esto se eliminó en algún lugar de la versión 4).
Google Closure tiene una buena función para esto ... goog.object.getCount (obj)
La forma en que resolví este problema es construir mi propia implementación de una lista básica que mantiene un registro de cuántos elementos se almacenan en el objeto. Es muy sencillo. Algo como esto:
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];
}
}
La implementación estándar del Objeto ( Propiedades y Métodos Internos del Objeto ES5.1 ) no requiere que un Object
realice un seguimiento de su número de claves / propiedades, por lo que no debería haber una manera estándar de determinar el tamaño de un Object
sin iterar explícita o implícitamente sobre sus claves .
Así que aquí están las alternativas más utilizadas:
1. Object.keys de ECMAScript ()
Object.keys(obj).length;
Funciona mediante la iteración interna de las claves para calcular una matriz temporal y devuelve su longitud.
- Pros - Sintaxis legible y limpia. No se requiere una biblioteca o código personalizado, excepto un shim si el soporte nativo no está disponible
- Contras - sobrecarga de memoria debido a la creación de la matriz.
2. Soluciones basadas en bibliotecas.
Muchos ejemplos basados en bibliotecas en otras partes de este tema son modismos útiles en el contexto de su biblioteca. Sin embargo, desde el punto de vista del rendimiento, no hay nada que ganar en comparación con un código perfecto sin biblioteca, ya que todos esos métodos de biblioteca en realidad encapsulan un Object.keys
-for-loop o ES5 Object.keys
(nativo o shimmed).
3. Optimizando un bucle for
La parte más lenta de dicho bucle for es generalmente la llamada .hasOwnProperty()
, debido a la función de sobrecarga de llamada. Entonces, cuando solo quiero el número de entradas de un objeto JSON, simplemente .hasOwnProperty()
llamada .hasOwnProperty()
si sé que ningún código no extendió el Object.prototype
.
De lo contrario, su código podría optimizarse muy ligeramente al hacer k
local ( var k
) y al usar el operador de incremento de prefijo ( ++count
) en lugar de postfix.
var count = 0;
for (var k in myobj) if (myobj.hasOwnProperty(k)) ++count;
Otra idea se basa en el almacenamiento en caché del método hasOwnProperty
:
var hasOwn = Object.prototype.hasOwnProperty;
var count = 0;
for (var k in myobj) if (hasOwn.call(myobj, k)) ++count;
Si esto es más rápido o no en un entorno dado es una cuestión de evaluación comparativa. De todos modos, se puede esperar una ganancia de rendimiento muy limitada.
No creo que esto sea posible (al menos no sin usar algunos elementos internos). Y no creo que ganes mucho optimizando esto.
Para aquellos que tengan Ext JS 4 en su proyecto puedes hacer:
Ext.Object.getSize(myobj);
La ventaja de esto es que funcionará en todos los navegadores compatibles con Ext (IE6-IE8 incluido), sin embargo, creo que el tiempo de ejecución no es mejor que el O (n), al igual que con otras soluciones sugeridas.
Para hacer esto en cualquier entorno compatible con ES5, como Node , Chrome, IE 9+, FF 4+ o Safari 5+:
Object.keys(obj).length
- Compatibilidad del navegador
- Documentación de Object.keys
- (incluye un método que puede agregar a navegadores que no sean ECMA5)
Para iterar en Avi Flax, responda Object.keys (obj) .length es correcto para un objeto que no tiene funciones vinculadas a él
ejemplo:
obj = {"lol": "what", owo: "pfft"};
Object.keys(obj).length; // should be 2
versus
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
/* obj === {"lol": "what", owo: "pfft", omg: function(){_.each(obj, function(a){arr.push(a);});}} */
pasos para evitar esto:
No ponga funciones en un objeto en el que desee contar el número de teclas
use un objeto separado o cree un nuevo objeto específicamente para funciones (si desea contar cuántas funciones hay en el archivo utilizando
Object.keys(obj).length
)
También sí, utilicé el módulo _ o guión bajo de nodejs en mi ejemplo
La documentación se puede encontrar aquí Underscore.js , así como su fuente en github y otra información adicional
Y finalmente, una implementación de lodash https://lodash.com/docs#size
_.size(obj)
Puede usar Object.keys(data).length
para encontrar la longitud del objeto JSON que tiene datos clave
Puede usar: Object.keys(objectName).length; & Object.values(objectName).length;
Object.keys(objectName).length; & Object.values(objectName).length;
Si está usando Underscore.js , puede usar _.size (gracias @douwe):
_.size(obj)
Alternativamente, también puede usar _.keys que podrían ser más claros para algunos:
_.keys(obj).length
Recomiendo encarecidamente Underscore, es una biblioteca apretada para hacer muchas cosas básicas. Siempre que sea posible, coinciden con ECMA5 y difieren a la implementación nativa.
De lo contrario apoyo la respuesta de @ Avi. Lo edité para agregar un enlace al documento MDC que incluye el método keys () que puede agregar a navegadores que no sean ECMA5.
Si jQuery anterior no funciona, intente
$(Object.Item).length