0

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?

David Ansermot
  • 6,052
  • 8
  • 47
  • 82
PrimuS
  • 2,505
  • 6
  • 33
  • 66

5 Answers5

5

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.

iCollect.it Ltd
  • 92,391
  • 25
  • 181
  • 202
3

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);
    }
});
WakeskaterX
  • 1,408
  • 9
  • 21
  • 1
    Of course you can iterate the properties of the one object. Just not the outer array. You should not need to change the data to match the code. – iCollect.it Ltd Apr 20 '15 at 15:18
  • 1
    The data structure is awkward, is all your data in that format? If so just pull out the data from the object and push it to an array. – WakeskaterX Apr 20 '15 at 15:22
3

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

CodingIntrigue
  • 75,930
  • 30
  • 170
  • 176
2

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" }
})
AJcodez
  • 31,780
  • 20
  • 84
  • 118
1

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.

JoshWillik
  • 2,624
  • 21
  • 38
  • 2
    *"`for( var i in champions )`"* Best to avoid using `for-in` to loop through arrays (without safeguards); that's not what it's for. (The *inner* loop is fine, though.) – T.J. Crowder Apr 20 '15 at 15:22
  • @T.J.Crowder ive ran into problems with for-in lately and was wondering what the correct usage of it is? I never really worked out what the issue was... I simply changed to a for loop and things worked! – BenjaminPaul Apr 20 '15 at 15:25
  • 1
    @BenjaminPaul: [Or my answer on the topic...](http://stackoverflow.com/questions/9329446/for-each-over-an-array-in-javascript/9329476#9329476) :-) – T.J. Crowder Apr 20 '15 at 15:28