Reputation: 115
I'm trying to learn JavaScript in Codecademy and one of the things mentioned briefly are "for in" loops. I've used them in a few of the exercises, but in this case I can't get it to work. I could do it with for (i = blah; etc), but I'd like to know what's wrong with this and if there's a way to fix it:
//Your three dimensional array from the last exercise probably
//looked something like this:
var hands = [];
hands[0] = [ [3,"H"], ["A","S"], [1,"D"], ["J","H"], ["Q","D"] ];
hands[1] = [ [9,"C"], [6,"C"], ["K","H"], [3,"C"], ["K","H"] ];
//Loop over every dimension in the array, logging out the suit and rank
//of each card in both hands
//1. loop over each hand
for (var hand in hands) {
//2. loop over each card array in each hand
for (var card in hand) {
//3. loop over each rank/suit array for each card in each hand
for (var prop in card) {
//4. log the value of the rank/suit array item
console.log(card[prop]);
}
}
}
The output is 0 0 0, instead of the number and suit. I tried placing console.log() after the first and second loop and I noticed it works correctly in the first, but not in the second one.
Upvotes: 3
Views: 7806
Reputation:
Momentarily ignoring the for-in
issue, your inner loops should look like this...
for (var hand in hands) {
for (var card in hands[hand]) {
for (var prop in hands[hand][card]) {
console.log(hands[hand][card][prop]);
}
}
}
Notice that each inner loop needs to explicitly reference the current value of its outer loop. You are iterating over the keys (the variable before in
) instead.
To deal with Arrays properly, you should almost always use a for
loop instead of for-in
.
for (var i = 0; i < hands.length; i++) {
for (var j = 0; j < hands[i].length; j++) {
for (var k = 0; k < hands[i][j].length; k++) {
console.log(hands[i][j][k]);
}
}
}
There are a few reasons for this, which you can find on StackOverflow.
To add clarity to the code, you can cache the current item in a variable...
for (var i = 0; i < hands.length; i++) {
var hand = hands[i]
for (var j = 0; j < hand.length; j++) {
var cards = hand[j];
for (var k = 0; k < cards.length; k++) {
console.log(cards[k]);
}
}
}
Upvotes: 11
Reputation: 546045
You shouldn't use for..in
loops on arrays, since it doesn't just loop over the indexed members of the array, but all properties of the object. Instead, you can use a 'traditional' for
loop, or the ECMAScript 5 .forEach
var hand, card, prop, h, c, p;
for (h = 0; h < hands.length; ++h) {
hand = hands[h];
for (c = 0; c < hand.length; ++c) {
card = hand[c];
for (p = 0; p < card.length; ++p) {
prop = card[p];
console.log(prop);
}
}
}
There are shorter ways to do the above, but that's a basic and readable method.
Upvotes: 2