1

I am surprised i have not faced this until today, but this costed me a whole day as I blindly believed my for...in will work as it should. Please help me understand why this happens with for...in ? Now i'm paranoid to use for...in.

I have simplified the example so that we can just focus on the root cause.

/** map data we are interested in looping */
let map = {
    '0': [],
    '1': ['1']
}

below are the different scenarios and there respective output.

/** 
 * Method 1: Trouble maker
 *
 * details: 
 * when debugged it picks up 1 and then jumps to 0 before going inside
 * the loop for printing console */
for(let val in map['1']){
    console.log(val); // gives 0
}

/** Method 2: using forEach but i cant use return */
map['1'].forEach((pre) => {
    console.log(pre); // gives 1
})

/** Method 3: this is more verbose but can always fallback */
let result = map['1'];
for(let i=0; i< result.length; i++){
    console.log(result[i]); // gives 1
}
Mad-D
  • 4,479
  • 18
  • 52
  • 93
  • 6
    To start with, you should NEVER use `for/in` to iterate an array. That is not what it is for. It iterates properties of an object which can include things other than elements of an array such as other properties on the array object that are not array elements. For a more detailed discussion of this issue, see https://stackoverflow.com/questions/22754315/for-loop-for-htmlcollection-elements/22754453#22754453. It is preferred to use `for/of` for array iteration now. – jfriend00 Dec 07 '21 at 04:23

4 Answers4

3

Your for...in loop is wrong. val should be the index of the array, so index 0 would be 1.
Example:

let map = {
    '0': [],
    '1': ['1']
}

const array = map['1'];

for(let index in array){
    console.log(array[index]); // gives 1
}
Capt 171
  • 665
  • 5
  • 15
3

Use for ... of

for(let val of map['1']){
    console.log(val);
}

for ... in loops over enumerable properties of an object.

for ... of statement creates a loop iterating over iterable objects.

MI Sabic
  • 367
  • 2
  • 7
  • 18
1

As you can see from For..in, the for...in statement are used to iterate through the property of an object, i.e. keys/indexes, so the reason that your for...in loop prints 0 is because it printed out each index through your array, which in this case will be "0" since your array only contains 1 element.

Leon.Z
  • 37
  • 2
1

for..in is wrong.

The for...in statement iterates a specified variable over all the enumerable properties of an object. For each distinct property, JavaScript executes the specified statements.

List item

You should use for...of loop.

The for...of statement creates a loop Iterating over iterable objects (including Array, Map, Set, arguments object and so on), invoking a custom iteration hook with statements to be executed for the value of each distinct property.

See more info in MDN

/** map data we are interested in looping */
let map = {
    '0': [],
    '1': ['1']
}

for(let val of map['1']){
    console.log(val); // gives 1
}
Ksengine
  • 61
  • 5