1

I am curious to know if you can place a for/in loop inside a for/in loop the way you can with a standard for loop. In the example below I am trying to list all of the properties of each game object but I am not getting the expected result. I have tried using dot notation and square brackets but neither seems to work. Is this not possible or am I overlooking something simple in the syntax?

var games = [{
    "name": "PCH Mystery Game",
    "maxScore": 50000,
    "levels": 4,
    "players": ["akshat", "joe", "dandan", "andrew"],
    "maps": {
      "1": 1,
      "2": 2,
      "3": 3,
      "4": 4
    }
  },
  {
    "name": "PCH Token Dash",
    "maxScore": 11500,
    "levels": 2,
    "players": ["andrew", "dandan", "matt", "mitchell", "hadi"],
    "maps": {
      "1": 1,
      "2": 2,
      "3": 3,
      "4": 4
    }
  },
  {
    "name": "PCH Balloon Drop",
    "maxScore": 500,
    "levels": 1,
    "players": [
      "akshat", "joe", "dandan", "dan", "mark", "nagesh", "jessie", "lou"
    ],
    "maps": {
      "1": 1,
      "2": 2,
      "3": 3,
      "4": 4
    }
  },
  {
    "name": "PCH Envelope Toss",
    "maxScore": 7000,
    "levels": 84,
    "players": ["akshat", "jessie", "joe", "andrew", "dandan"],
    "maps": {
      "1": 1,
      "2": 2,
      "3": 3,
      "4": 4
    }
  },
  {
    "name": "PCH Prize Patrol Race",
    "maxScore": 100000,
    "levels": 5,
    "players": [
      "akshat", "joe", "andrew", "dandan", "lou", "roberto", "jessie", "haim", "matt", "mitchell", "ian"
    ],
    "maps": {
      "1": 1,
      "2": 2,
      "3": 3,
      "4": 4
    }
  }
];

for (game in games) {
  document.write("game: " + games[game].name + "<br>");
  for (prop in game) {
    document.write("property name: " + prop + "<br>");
    document.write("property value: " + game[prop] + "<br>");
    document.write("property value: " + game.prop + "<br>");
  }
  document.write("<br>");
}

4
  • 2
    It has to be for(prop in games[game]), game is the key and not the value. Commented Apr 11, 2018 at 16:14
  • It is always valuable to describe the logic for oneself in text first. Commented Apr 11, 2018 at 16:16
  • 1
    stackoverflow.com/questions/500504/… Commented Apr 11, 2018 at 16:16
  • The best part of JavaScript literal objects is being able to get the data without iterate too much. If you have control over the type of object you have you can get the data by the keys. As far as I know, it is possible to make a for in inside a for in. Commented Apr 11, 2018 at 16:18

2 Answers 2

5

Fundamentally, yes, you can have nested for-in loops. That's not the problem in your code.

The variable in a for-in loop is the property name (or key), not the actual value. Separately, for-in isn't the correct way to loop through an array (although you can make it work if you try). See my answer here for a list of ways to loop through arrays.

In this case, you'd probably use forEach or (in modern environments) for-of or just a simple for loop for the outer loop through the array, and then a for-in loop (over the object properties)

games.forEach(function(game) {
    for (var prop in game) {
        console.log("property name: " + prop);
        console.log("property value: " + game[prop]);
    }
});

Live Example:

var games = [{
    "name": "PCH Mystery Game",
    "maxScore": 50000,
    "levels": 4,
    "players": ["akshat", "joe", "dandan", "andrew"],
    "maps": {
      "1": 1,
      "2": 2,
      "3": 3,
      "4": 4
    }
  },
  {
    "name": "PCH Token Dash",
    "maxScore": 11500,
    "levels": 2,
    "players": ["andrew", "dandan", "matt", "mitchell", "hadi"],
    "maps": {
      "1": 1,
      "2": 2,
      "3": 3,
      "4": 4
    }
  },
  {
    "name": "PCH Balloon Drop",
    "maxScore": 500,
    "levels": 1,
    "players": [
      "akshat", "joe", "dandan", "dan", "mark", "nagesh", "jessie", "lou"
    ],
    "maps": {
      "1": 1,
      "2": 2,
      "3": 3,
      "4": 4
    }
  },
  {
    "name": "PCH Envelope Toss",
    "maxScore": 7000,
    "levels": 84,
    "players": ["akshat", "jessie", "joe", "andrew", "dandan"],
    "maps": {
      "1": 1,
      "2": 2,
      "3": 3,
      "4": 4
    }
  },
  {
    "name": "PCH Prize Patrol Race",
    "maxScore": 100000,
    "levels": 5,
    "players": [
      "akshat", "joe", "andrew", "dandan", "lou", "roberto", "jessie", "haim", "matt", "mitchell", "ian"
    ],
    "maps": {
      "1": 1,
      "2": 2,
      "3": 3,
      "4": 4
    }
  }
];

games.forEach(function(game) {
    for (var prop in game) {
        console.log("property name: " + prop);
        console.log("property value: " + game[prop]);
    }
});

But you have lots of options, particularly in modern environments. For instance:

for (const game of games) {
    for (const [prop, value] of Object.entries(game)) {
        console.log(`${prop} is ${value}`);
    }
}

...uses for-of, destructuring, and Object.entries.

Live Example:

var games = [{
    "name": "PCH Mystery Game",
    "maxScore": 50000,
    "levels": 4,
    "players": ["akshat", "joe", "dandan", "andrew"],
    "maps": {
      "1": 1,
      "2": 2,
      "3": 3,
      "4": 4
    }
  },
  {
    "name": "PCH Token Dash",
    "maxScore": 11500,
    "levels": 2,
    "players": ["andrew", "dandan", "matt", "mitchell", "hadi"],
    "maps": {
      "1": 1,
      "2": 2,
      "3": 3,
      "4": 4
    }
  },
  {
    "name": "PCH Balloon Drop",
    "maxScore": 500,
    "levels": 1,
    "players": [
      "akshat", "joe", "dandan", "dan", "mark", "nagesh", "jessie", "lou"
    ],
    "maps": {
      "1": 1,
      "2": 2,
      "3": 3,
      "4": 4
    }
  },
  {
    "name": "PCH Envelope Toss",
    "maxScore": 7000,
    "levels": 84,
    "players": ["akshat", "jessie", "joe", "andrew", "dandan"],
    "maps": {
      "1": 1,
      "2": 2,
      "3": 3,
      "4": 4
    }
  },
  {
    "name": "PCH Prize Patrol Race",
    "maxScore": 100000,
    "levels": 5,
    "players": [
      "akshat", "joe", "andrew", "dandan", "lou", "roberto", "jessie", "haim", "matt", "mitchell", "ian"
    ],
    "maps": {
      "1": 1,
      "2": 2,
      "3": 3,
      "4": 4
    }
  }
];

for (const game of games) {
    for (const [prop, value] of Object.entries(game)) {
        console.log(`${prop} is ${value}`);
    }
}

Sign up to request clarification or add additional context in comments.

Comments

0

Clearer than for(prop in games[game]) is

for (i in games) {
  var game = games[i];
  document.write("game: " + game.name + "<br>");
  for (prop in game) {
    document.write("property name: " + prop + "<br>");
    document.write("property value: " + game[prop] + "<br>");
  }
  document.write("<br>");
}

Note that for...in is not typically used in arrays as much, since arrays are typically expected to have an order and for...in won't necessarily respect order. It's a few more keystrokes, but there's nothing wrong with for (i = 0; i < games.length; i++) and then continuing the same way.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.