PrimuS
PrimuS

Reputation: 2683

JSON array only gives "1" as length, cannot loop through

I have the following json array:

var champions = [{
  "1":{
    "name":"Aatrox",
    "role1":"Top",
    "role2":"Jungle"},
  "2":{
    "name":"Ahri",
    "role1":"Middle"},
  "3":{"
    name":"Akali",
    "role1":"Middle",
    "role2":"Top"
   }
}];

and I trying to loop through this array with a code snippet I found:

$(document).ready(function(){
    var x = 1;
    for(var i = 0; i < champions.length; i++) {
        console.log(champions[i][x].name);
        x++;
    }
});

But it only gives me "Aatrox" and stops as champions.length is 1.
How can I loop through the array for all names?

Upvotes: 0

Views: 133

Answers (5)

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93561

Assuming you do not wish to change your data structure, you can iterate the array and then the properties of each object within it (then access the name):

var champions = [{
  "1":{
    "name":"Aatrox",
    "role1":"Top",
    "role2":"Jungle"},
  "2":{
    "name":"Ahri",
    "role1":"Middle"},
  "3":{
      "name":"Akali",
    "role1":"Middle",
    "role2":"Top"
   }
}];

$(document).ready(function(){
    for(var i = 0; i < champions.length; i++) {
        for (var prop in champions[i]){
            console.log(champions[i][prop].name);
        }
    }
});

JSFiddle: http://jsfiddle.net/TrueBlueAussie/234yspw1/

Note: The order they are returned is undefined, so you should not count on that.

JSFiddle: http://jsfiddle.net/TrueBlueAussie/234yspw1/1/

If order is important you need to restructure your data to be an array.

Upvotes: 5

AJcodez
AJcodez

Reputation: 34166

It's an array of length one. Iterate objects like so:

var champs = champions[0]
var keys = Object.keys(champs)

// if you need them in order
keys = keys.map(Number).sort().map(String)

// iterate
keys.forEach(function (key, index) {
   console.log(key)           // "1"
   console.log(champs[key])   // { "name": "etc" }
})

Upvotes: 2

WakeskaterX
WakeskaterX

Reputation: 1428

Edit: Working JS Fiddle: https://jsfiddle.net/3ms8s9jr/

var champions = [{
  "1":{
    "name":"Aatrox",
    "role1":"Top",
    "role2":"Jungle"},
  "2":{
    "name":"Ahri",
    "role1":"Middle"},
  "3":{"
    name":"Akali",
    "role1":"Middle",
    "role2":"Top"
   }
}];

needs to be:

var champions = [
  {
    "name":"Aatrox",
    "role1":"Top",
    "role2":"Jungle"
  },
  {
    "name":"Ahri",
    "role1":"Middle"
  },
  { 
    "name":"Akali",
    "role1":"Middle",
    "role2":"Top"
  }
];

You need to have one object per champion, right now you have them all stored in one big object, so you can't loop through it easily (rather, it's just awkward to do it effectively).

Ideally you want to have your data in a format that is easy to use, so converting the data if you need to into an array is probably going to be the best long term option.

Loop through that like this:

$(document).ready(function(){
    for(var i = 0; i < champions.length; i++) {
        console.log(champions[i].name);
    }
});

Upvotes: 3

JoshWillik
JoshWillik

Reputation: 2645

If you want to loop this array

var champions = [{
  "1":{
    "name":"Aatrox",
    "role1":"Top",
    "role2":"Jungle"},
  "2":{
    "name":"Ahri",
    "role1":"Middle"},
  "3":{"
    name":"Akali",
    "role1":"Middle",
    "role2":"Top"
   }
}];

Your code will need to look like this

for( var i = 0, end = champions.length; i < end; i++ ){
  for( var attr in champions[i] ){
    if( !champions[i].hasOwnProperty( attr ) ){
      continue
    }
    // champions[i][attr] is the champion here
  }

Alternateley, you can convert your odd looking json to a regular array with this rather strange looking bit of code.

var championsArray = Array.prototype.splice.call( champions[0] )

Then loop through it normally.

Upvotes: 1

CodingIntrigue
CodingIntrigue

Reputation: 78525

Note: As everyone has pointed out, your data structure is a little odd. The best idea is to make sure your array is correctly structured so that you can iterate it as an array, but you can also iterate an array containing a single object:

jQuery's each does a good job of iterating objects & keys:

if(champions.length) {
    $.each(champions[0], function(key, value) {
        console.log(value.name);
    });
}

jsFiddle

Upvotes: 3

Related Questions