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

เวอร์ชัน Iterable

สิ่งนี้จะทำงานเมื่อกำหนดเป้าหมาย 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
@Mick มันขึ้นอยู่กับเป้าหมาย เมื่อเปลี่ยนไปใช้ ES6 จะไม่ทำเช่นนั้น เหตุผลสำหรับรหัสพิเศษนั้นเมื่อทำการ transpiling คือการรับรหัส ES6 ให้ทำงานในเวอร์ชันที่ผ่านมาเท่านั้น
David Sherret

3
คุณจะหยุดพักได้อย่างไร ในแต่ละที่?
João Silva

ยังเป็นคำตอบที่ดีstackoverflow.com/questions/34348937/…
Christopher Grigg

@ 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 runtimes


35

"Old School javascript" เพื่อช่วยเหลือ (สำหรับผู้ที่ไม่คุ้นเคย / ชอบการเขียนโปรแกรมใช้งาน)

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

2
ฉันชอบคำตอบนี้ดีที่สุด ไม่มีการใช้วิธีการพิเศษเพื่อสร้างดัชนีสำหรับแต่ละองค์ประกอบ
bluegrounds

ขอบคุณมาก ๆ ๆ ๆ 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 พร้อมสำหรับ .. in loop การดำเนินการทางคณิตศาสตร์ด้วย "i" จะส่งผลให้มีการต่อสตริง (i + 1) จะเท่ากับ "01" เช่นเมื่อ i = 0
Stéphane

for..inยังสามารถให้คุณมากกว่าที่คุณคาดหวังเพราะมันรวมฟังก์ชั่นทั้งหมดที่ประกาศบนวัตถุด้วย ตัวอย่างเช่น:for (var prop in window.document) { console.log(prop); }
Ken Lyon

5

หรือวิธีแก้ปัญหาโรงเรียนเก่าอื่น:

var someArray = [9, 2, 5];
let i = 0;
for (var item of someArray) {
    console.log(item); // 9,2,5
    i++;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.