2010-08-20 13 views
7

Déjame explicarte en detalle. Tengo debajo de un objeto conmigo -¿Hay alguna forma de obtener el número de elementos del objeto?

{ 
    "OBJECT1" : { 
     "NAME1" : "VALUE1", 
     "NAME2" : "VALUE2", 
     "NAME3" : "VALUE3" 
    }, 
    "OBJECT2" : { 
     "NAME4" : "VALUE4", 
     "NAME5" : "VALUE5" 
    } 
} 

A partir de este objeto, quiero conseguir algo así como el número de elementos en OBJETO1 = 3 y el número de elementos en OBJETO2 = 2. Si en todo esto es posible usando javascript. Básicamente, lo que intento hacer es recorrer los pares de valores nominales disponibles en el objeto dinámicamente para que, si alguien agrega otro elemento a un objeto, no tenga que cambiar mi código.

También se descarta cualquier alternativa ya que solo puedo usar objetos en mi caso de uso.

+0

posible duplicado de [Longitud de Javascript asociativa Array] (http://stackoverflow.com/questions/5223/length-of-javascript-associative-array) – kennytm

+2

Esos objetos no son llamados objetos JSON. JSON es solo una notación que representa objetos * JavaScript *. –

+1

@Marcel Korpel: entonces, ¿es posible decir que esa cadena JSON como vemos aquí es una forma serializada de un objeto JS? – Piskvor

Respuesta

9

Sin la conversión de su objeto que podría iterar a través del objeto contando propiedades de este modo:

function countObjectProperties(obj) 
{ 
    var count = 0; 
    for(var i in obj) 
     if(obj.hasOwnProperty(i)) 
      count++; 

    return count; 
} 

Ampliando sobre por qué es necesario utilizar hasOwnProperty como dije en el comentario a continuación, puede encontrarse con un problema en el que una biblioteca o un navegador ha agregado métodos y propiedades a los Objetos, para evitar el conteo, buscamos hasOwnProperty antes de contarlo. More details at MSDN o al Mozilla Developer Center

+0

¿por qué es necesario HasOwnProperty (solo preguntar)? – KeatsPeeks

+0

Impresionante, esto funciona bien para mí. Muchas gracias. –

+2

@Samuel_xL Necesita hasOwnProperty para evitar las funciones de conteo y otros complementos no deseados que el navegador y/o complementos podrían haber agregado. –

4

Para la cadena JSON que representa un objeto (que es su caso), no puede usar ninguna propiedad de longitud. necesita pasar por el objeto (ver la respuesta de Kristoffer S Hansen).

Si representaba una gama, se puede obtener la longitud con:

var len = arr.length; 

jQuery hace que sea más sencillo:

var len = $(JSON).length; 
+2

No Jquery por favor y también se supone que debo evitar la evaluación en los estándares de mi proyecto. –

+0

eval era para el ejemplo de matriz, que no necesita de todos modos. Era solo información adicional :) Ok, he eliminado la evaluación ya que está fuera de tema. – KeatsPeeks

+0

No use 'eval' si no es necesario. – Gumbo

1

Para responder a su objetivo más amplio, tal como se especifica en su pregunta:

Para recorrer las propiedades, puede usar la construcción for..in:

for (var item in myobject) { 
    // some browsers add more properties to every object, we don't want those 
    if (myobject.hasOwnProperty(item)) { 
    do_something(item); 
    } 
} 

Suponiendo que myobject es el objeto de su pregunta, este bucle voluntad a través de él y llamar do_something(OBJECT1) y do_something(OBJECT2); se puede utilizar el mismo constructo de bucle a través de los objetos secundarios:

// loop through OBJECT1 and OBJECT2 
for (var item in myobject) { 
    // some browsers add more properties to every object, we don't want those 
    if (myobject.hasOwnProperty(item)) { 
    // loop through the item's children 
    for (var pair in item) { 
     if (item.hasOwnProperty(pair)) { 
     // each of the name:value pairs will be passed to this 
     do_something_else(item,pair); 
     } 
    } 
    } 
} 
+0

En el segundo fragmento, parece que 'item' ya es la * clave * de cada par de clave-valor, por lo que no tiene sentido volver a iterar sobre él ... – Timwi

+0

@Timwi: En realidad, no: en el ciclo externo, iteramos sobre las propiedades de nivel superior, es decir, OBJECT1 y OBJECT2. En el ciclo interno, iteramos sobre * sus * propiedades, es decir, NAME1, NAME2, NAME3 y NAME4, NAME5, respectivamente. Si el anidamiento fue más allá, podríamos iterar sobre los objetos más profundos (tal vez podría usarse la recursión). – Piskvor

+0

Para aclarar, en el segundo ciclo estoy iterando las propiedades de una propiedad del objeto de nivel superior ('myobject.OBJECT1.NAME1', etc.). Esta anidación podría ser más profunda, pero no en este caso. – Piskvor

Cuestiones relacionadas