Get loop counter/index using for…of syntax in JavaScript
counter, for-loop, foreach, javascript
Solution
`for…in` iterates over property names, not values, and does so in an unspecified order (yes, even after ES6). You shouldn’t use it to iterate over arrays. For them, there’s ES5’s `forEach` method that passes both the value and the index to the function you give it:
var myArray = [123, 15, 187, 32];
myArray.forEach(function (value, i) {
console.log('%d: %s', i, value);
});
// Outputs:
// 0: 123
// 1: 15
// 2: 187
// 3: 32
Or ES6’s `Array.prototype.entries`, which now has support across current browser versions:
for (const [i, value] of myArray.entries()) {
console.log('%d: %s', i, value);
}
For iterables in general (where you would use a `for…of` loop rather than a `for…in`), there’s nothing built-in, however:
function* enumerate(iterable) {
let i = 0;
for (const x of iterable) {
yield [i, x];
i++;
}
}
for (const [i, obj] of enumerate(myArray)) {
console.log(i, obj);
}
If you actually did mean `for…in` – enumerating properties – you would need an additional counter. `Object.keys(obj).forEach` could work, but it only includes own properties; `for…in` includes enumerable properties anywhere on the prototype chain.
Problem
I understand that the basic `for...of` syntax in JavaScript looks like this: ``` for (let obj of myArray) { // ... } ``` But how do I get the loop counter/index when iterating with this syntax? (With the same question applying to `for...in` notation for iterating over object property names) I know I can use an explicit loop counter like: ``` for (let i = 0; i < myArray.length; i++) { const obj = myArray[i]; console.log(i); } ``` Or manually track the index outside of the loop: ``` let i = 0; for (let obj of myArray) { console.log(i); i++; } ``` But I would rather use the simpler `for...of` loop, I think they look better and make more sense. As an example of a language that lets you do this, in Python it's as easy as: ``` for i, obj in enumerate(my_array): print(i) ```