HiveBrain v1.2.0
Get Started
← Back to all entries
patterntypescriptCritical

TypeScript for ... of with index / key?

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
typescriptindexwithkeyfor

Problem

As described here TypeScript introduces a foreach loop:

var someArray = [9, 2, 5];
for (var item of someArray) {
    console.log(item); // 9,2,5
}


But isn't there any index/key? I would expect something like:

for (var item, key of someArray) { ... }

Solution

.forEach already has this ability:

const someArray = [9, 2, 5];
someArray.forEach((value, index) => {
    console.log(index); // 0, 1, 2
    console.log(value); // 9, 2, 5
});


But if you want the abilities of for...of, then you can map the array to the index and value:

for (const { index, value } of someArray.map((value, index) => ({ index, value }))) {
    console.log(index); // 0, 1, 2
    console.log(value); // 9, 2, 5
}


That's a little long, so it may help to put it in a reusable function:

function toEntries(a: T[]) {
    return a.map((value, index) => [index, value] as const);
}

for (const [index, value] of toEntries(someArray)) {
    // ..etc..
}


Iterable Version

This will work when targeting ES3 or ES5 if you compile with the --downlevelIteration compiler option.

function* toEntries(values: T[] | IterableIterator) {
    let index = 0;
    for (const value of values) {
        yield [index, value] as const;
        index++;
    }
}


Array.prototype.entries() - ES6+

If you are able to target ES6+ environments then you can use the .entries() method as outlined in Arnavion's answer.

Code Snippets

const someArray = [9, 2, 5];
someArray.forEach((value, index) => {
    console.log(index); // 0, 1, 2
    console.log(value); // 9, 2, 5
});
for (const { index, value } of someArray.map((value, index) => ({ index, value }))) {
    console.log(index); // 0, 1, 2
    console.log(value); // 9, 2, 5
}
function toEntries<T>(a: T[]) {
    return a.map((value, index) => [index, value] as const);
}

for (const [index, value] of toEntries(someArray)) {
    // ..etc..
}
function* toEntries<T>(values: T[] | IterableIterator<T>) {
    let index = 0;
    for (const value of values) {
        yield [index, value] as const;
        index++;
    }
}

Context

Stack Overflow Q#36108110, score: 482

Revisions (0)

No revisions yet.