2012-04-08 11 views
34

Estoy tratando de usar una tabla hash para poder seleccionar un objeto específico almacenado en una matriz/objeto. Sin embargo, estoy teniendo un problema al pasar por un objeto.Iterar a través de una tabla hash de objetos

var pins= {}; 
pins[6] = '6'; 
pins[7] = '7'; 
pins[8] = '8'; 

$('#result3').append('<div>Size: ' + Object.size(pins) + '</div>'); 
for(var i = 0; i < Object.size(pins); i++) { 
    $('#result3').append('<div>' + pins[i] + '</div>'); 
} 

jsFiddle: http://jsfiddle.net/7TrSU/

Como se puede ver en TEST 3 que utiliza objeto pin para almacenar los datos, que estoy recibiendo undefined cuando un bucle a través del objeto pin.

¿Cuál es la forma correcta de pasar por pin?

EDITAR

¿Qué pasa si en lugar de simplemente pin[6] = '6', hago pasador [6] = un objeto y quiero colocar a través de las propiedades de todos sus id? código real fragmento de lo que estoy haciendo ...

for(var i = 0; i < json.length; i++) { 
    markerId = json[i].listing_id 

    // Place markers on map 
    var latLng = new google.maps.LatLng(json[i].lat, json[i].lng); 
    var marker = new google.maps.Marker({ 
       listing_id: markerId, 
       position: latLng, 
       icon: base_url + 'images/template/markers/listing.png', 
    }); 

    markers[markerId] = marker; 
} 

for(var marker in markers) { 
    console.log('marker ID: ' + marker.listing_id); 
    mc.addMarker(marker); 
} 

El console.log anterior devuelve indefinido, y si lo hago console.log(marker) lugar, consigo el valor de marker.listing_id. Lo siento, estoy confundido!

me las arreglé para conseguir que funcione con $.each(markers, function(i, marker){}); pero ¿por qué el for..in anterior no funciona?

+2

Está añadiendo miembros a índices 6, 7 y 8, pero la iteración de 0 a 2. Una mejor estrategia sería para iterar de '0' a' length-1' y probar si los miembros existen antes de intentar usarlo. – RobG

+0

está confundiendo _arrays_ con _objetos_. – c69

+0

@ c69-las matrices son objetos, ;-) El problema de OP es tratar de acceder a las propiedades que no existen. – RobG

Respuesta

38

No utilice un lazo for(i=0; i<size; i++). En su lugar, utilice:

  1. Object.keys(pins) para obtener una lista de propiedades, y el bucle a través de él, o
  2. Utilice un for (key_name in pins) conjuntamente con Object.hasOwnProperty (para excluir propiedades heredan) para recorrer las propiedades.

El problema de su caso tercera prueba es que lee los valores de las teclas 0, 1 y 2 (en lugar de 6, 7, 8).

-1

La pin comienza con 6 hasta 8, pero la de bucles forza desde 0 hasta 3 (la longitud del objeto). Debe hacer un bucle desde 6 hasta 6 + the_size_of_the_object.Algo como esto:

for(var i = 6, len = 6 + Object.size(pins); i < len; i++) { 
    $('#result3').append('<div>' + pins[i] + '</div>'); 
} 

O algo así, esto es lo que me gusta:

for(var i = 5; pin = pins[++i];) { 
    $('#result3').append('<div>' + pin + '</div>'); 
} 
+0

Eso sería mejor si agrega 'if (pin.hasOwnProperty (i)) ...' antes de intentar usar el miembro para eliminar los que no existen. – RobG

84
var hash = {} 
hash[key] = value 

Object.keys(hash).forEach(function (key) { 
    var value = hash[key] 
    // iteration code 
}) 
+0

La variable de valor se crea después de ser utilizada. – Yster

3

dado que está utilizando jQuery:

jQuery.each(pins, function (name, value) { 
    $('#result3').append('<div>' + name + "=" + value + '</div>'); 
}); 
+0

Utilicé su método y funciona de la manera que quiero, pero no entiendo por qué el uso de 'for..in' no funciona como se desea ... Actualización de publicación original ... – Nyxynyx

+0

Porque estaba usando' para. .in' contar el número de elementos, no para encontrar sus nombres. Una vez que descubrió que había tres elementos, mira los artículos llamados 0, 1 y 2, pero los artículos se llamaron 6, 7 y 8. – Quentin

2

Prueba esto :

for (var pin in pins) { 
    $('#result3').append('<div>' + pin + '</div>'); 
} 

Example fiddle

+1

para ... los bucles son sub óptimos – Raynos

+3

@Raynos no, no lo son. La ausencia de 'hasOwnProperty', sin embargo, sí lo es. – c69

+1

@ c69 'for ... in' sigue siendo subóptimo porque es menos eficiente que' Object.keys'. 'hasOwnProperty' es una llamada costosa – Raynos

2
function iterate(obj){ 
    var keys = Object.keys(obj); 
    for(i in keys){ 
     doSomething(obj[keys[i]].id); 
    } 
} 

Este itera sobre la id de todos los campos en cualquier objeto

Cuestiones relacionadas