views:

185

answers:

4

I have a two dimensional JSON array where each element contains several attributes. The example below is intentionally simplified:

var map_data = { "1":
                      {"1":{"name":"aa"},"2":{"name":"bb"}},
                 "2":
                      {"1":{"name":"cc"},"2":{"name":"dd"}}
               };

I try to parse the data but .length doesn't work:

for(x=1; x<=map_data.length; x++) { 
    for(y=1; y<=map_data[x].length; y++) {
        // CODE 
    }
}

Many, many thanks!

+1  A: 

Since map_data is an object instead of an array you need to use for/in loop:

for (var x in map_data) {
  // check for hasOwnProperty omitted for simplicity.
  for (var y in map_data[x]) {
    // CODE.
  }
}

But it's better to send that JSON as an array [a,b,c] instead of an object {"0":a,"1":b,"2":c}.

KennyTM
A: 

Use the for .. in construct:

for (var m in map_data) {
     // ...
}

Also, I must note that this isn't a "JSON array", but rather a nested object. JSON is just the string representation of nested JS objects and arrays.

Eli Bendersky
+1  A: 

hasOwnProperty is used to determine whether an object has the specified property as a direct property of that object with no respect to it's prototype chain.

for(var i in map_data){
    if(map_data.hasOwnProperty(i)){
        for(var j in map_data[i]){
            if(map_data[i].hasOwnProperty(j)){
                /*do whatever you want with map_data[i][j]*/
            }
        }
    }
}
Li0liQ
+3  A: 

That's not an array, they are simple objects, that's why you cannot use the length property.

You need to use the for...in statement:

for(var x in map_data) { 
  if (map_data.hasOwnProperty(x))
    for(var y in map_data[x]) {
      if (map_data[x].hasOwnProperty(y)) {
        // CODE
      }
    }
}

The hasOwnProperty checks are because this statement iterates over all properties, inherited or not, and if something (like some JavaScript frameworks) augmented the Array.prototype or Object.prototype objects, those augmented properties will be also iterated.

You should know that this statement doesn't ensure anyhow the order of iteration.

I would recommend you to use a "real" array:

[
 [{"name":"aa"},{"name":"bb"}],
 [{"name":"cc"},{"name":"dd"}]
]

In this way you will be able to use the length property to iterate over the indexes.

CMS
+1 for pointing in the direction of a real array. It never ceases to amaze me how many questions involve setting numerical index properties on objects.
Andy E