TypeScript для… індексу / ключа?


146

Як описано тут, TypeScript вводить цикл foreach:

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

Але хіба немає індексу / ключа? Я б очікував чогось типу:

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

Відповіді:


274

.forEach вже має цю здатність:

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

Але якщо ви хочете здібностей for...of, то ви можете mapмасив до індексу та значення:

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..
}

Ітерабельна версія

Це буде працювати при націлюванні на ES3 або ES5, якщо ви компілюєте з параметром --downlevelIterationкомпілятора.

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

Array.prototype.entries () - ES6 +

Якщо ви можете орієнтуватися на середовища ES6 +, тоді ви можете скористатися .entries()методом, визначеним у відповіді Arnavion .


Але TypeScript компілює "для ... з" у простий "для", який має індекс var _i. Тож розробникам TypeScript було б легко дозволити нам використовувати цей _i. Дивіться приклад ігрового майданчика: bit.ly/1R9SfBR
Mick

2
@Мік, це залежить від цілі. При перекладанні на ES6 це не робити. Причиною цього додаткового коду при трансляції є лише те, щоб код ES6 працював у попередніх версіях.
Девід Шеррет

3
Як можна зробити перерву; в тому для кожного?
Жоао Сільва

Також хороша відповідь stackoverflow.com/questions/34348937/…
Крістофер Грігг

@ JoãoSilva ви можете використовувати Array.some()та повертати помилкові під час ітерації, яку ви хочете зупинити. Це не так настільки чітко чи красиво, як, breakале це дозволить виконати роботу. Особисто мені це не подобається, я, певно, переписав би ітерацію іншим способом :) див. Stackoverflow.com/questions/2641347/…
Neek

36

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries

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

У TS це вимагає орієнтації на ES2015, оскільки воно вимагає виконання часу для підтримки ітераторів , а виконання ES5 не виконує. Звичайно, ви можете використовувати щось на зразок Babel, щоб зробити висновок робочим для ES5.


35

"Old school javascript" на допомогу (для тих, хто не знайомий / любить функціональне програмування)

for (let i = 0; i < someArray.length ; i++) {
  let item = someArray[i];
}

2
Я справді вважаю за краще цю відповідь. Немає використання додаткових методів просто для створення індексу для кожного елемента.
bluegrounds

Дякую youuu veryyyy muuuchh! Ми цього не знали :)
TSR

14

Ви можете використовувати оператор for..in TypeScript для доступу до індексу при роботі з колекціями.

var test = [7,8,9];
for (var i in test) {
   console.log(i + ': ' + test[i]);
} 

Вихід:

 0: 7
 1: 8
 2: 9

Див. Демо


Майте на увазі, що "i" - це рядок, а не int з циклом for..in. Виконання арифметичної операції з "i" призведе до конкатенації рядків. (Г + 1) буде дорівнює "01", наприклад , коли r = 0
Стефан

for..inтакож може дати вам більше, ніж ви очікували, оскільки воно включає всі функції, оголошені також на об'єкті. Наприклад:for (var prop in window.document) { console.log(prop); }
Кен Ліон

5

Або інше рішення для старої школи:

var someArray = [9, 2, 5];
let i = 0;
for (var item of someArray) {
    console.log(item); // 9,2,5
    i++;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.