พจนานุกรม - การวนซ้ำบน Typescript Map
ฉันกำลังพยายามวนซ้ำในแผนที่ของ TypeScript แต่ฉันมักจะเจอข้อผิดพลาดและยังหาวิธีแก้ปัญหาสำหรับปัญหาเล็กน้อยแบบนี้ไม่ได้เลย
รหัสของฉันคือ:
myMap : Map<string, boolean>;
for(let key of myMap.keys()) {
console.log(key);
}
และฉันได้รับข้อผิดพลาด:
ประเภท 'IterableIteratorShim<[string, boolean]>' ไม่ใช่ประเภทอาร์เรย์หรือประเภทสตริง
แทรซ์เต็ม
Error: Typescript found the following errors:
/home/project/tmp/broccoli_type_script_compiler-input_base_path-q4GtzHgb.tmp/0/src/app/project/project-data.service.ts (21, 20): Type 'IterableIteratorShim<[string, boolean]>' is not an array type or a string type.
at BroccoliTypeScriptCompiler._doIncrementalBuild (/home/project/node_modules/angular-cli/lib/broccoli/broccoli-typescript.js:115:19)
at BroccoliTypeScriptCompiler.build (/home/project/node_modules/angular-cli/lib/broccoli/broccoli-typescript.js:43:10)
at /home/project/node_modules/broccoli-caching-writer/index.js:152:21
at lib$rsvp$$internal$$tryCatch (/home/project/node_modules/rsvp/dist/rsvp.js:1036:16)
at lib$rsvp$$internal$$invokeCallback (/home/project/node_modules/rsvp/dist/rsvp.js:1048:17)
at lib$rsvp$$internal$$publish (/home/project/node_modules/rsvp/dist/rsvp.js:1019:11)
at lib$rsvp$asap$$flush (/home/project/node_modules/rsvp/dist/rsvp.js:1198:9)
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
ฉันกำลังใช้ angular-cli beta5 และ typescript 1.8.10 และเป้าหมายของฉันคือ es5 มีใครเคยเจอปัญหานี้ไหม?
คำตอบ #1
คุณสามารถใช้ Map.prototype.forEach((value, key, map) => void, thisArg?) : void แทนได้
ใช้มันแบบนี้:
myMap.forEach((value: boolean, key: string) => {
console.log(key, value);
});
คำตอบ #2
es6
for (let [key, value] of map) {
console.log(key, value);
}
es5
for (let entry of Array.from(map.entries())) {
let key = entry[0];
let value = entry[1];
}
คำตอบ #3
เพียงแค่ใช้เมธอด Array.from() เพื่อแปลงมันเป็น Array:
myMap : Map<string, boolean>;
for(let key of Array.from( myMap.keys()) ) {
console.log(key);
}
คำตอบ #4
นี่ใช้ได้ผลสำหรับฉัน เวอร์ชันของ TypeScript: 2.8.3
for (const [key, value] of Object.entries(myMap)) {
console.log(key, value);
}
คำตอบ #5
การใช้ Array.from, Array.prototype.forEach() และฟังก์ชันลูกศร:
ทำซ้ำผ่าน คีย์:
Array.from(myMap.keys()).forEach(key => console.log(key));
ทำซ้ำผ่าน ค่า:
Array.from(myMap.values()).forEach(value => console.log(value));
ทำซ้ำใน รายการ:
Array.from(myMap.entries()).forEach(entry => console.log('Key: ' + entry[0] + ' Value: ' + entry[1]));
คำตอบ #6
ตามบันทึกการอัปเดต TypeScript 2.3 เกี่ยวกับ "--downlevelIteration ใหม่"
for..of statements, การสลาย Array, และองค์ประกอบ Spread ใน Array, Call, และ New expressions รองรับ Symbol.iterator ใน ES5/E3 หากมีเมื่อใช้--downlevelIteration
นี่ไม่ได้เปิดใช้งานโดยค่าเริ่มต้น! เพิ่ม "downlevelIteration": true ลงใน tsconfig.json ของคุณ หรือใช้ตัวเลือก --downlevelIteration กับ tsc เพื่อรับการสนับสนุนตัวทำซ้ำอย่างเต็มรูปแบบ
เมื่อมีสิ่งนี้อยู่ คุณสามารถเขียน for (let keyval of myMap) {...} และประเภทของ keyval จะถูกอนุมานโดยอัตโนมัติ
ทำไมสิ่งนี้ถึงถูกปิดโดยค่าเริ่มต้น? ตามที่ผู้ร่วมพัฒนา TypeScript @aluanhaddad กล่าว
มันเป็นทางเลือกเพราะมันมีผลกระทบอย่างมากต่อขนาดของโค้ดที่สร้างขึ้น และอาจส่งผลต่อประสิทธิภาพ สำหรับการใช้งาน iterable ทั้งหมด (รวมถึง arrays)
ถ้าคุณสามารถตั้งเป้าเป็น ES2015 ("target": "es2015" ใน tsconfig.json หรือ tsc --target ES2015) หรือเวอร์ชันที่ใหม่กว่า การเปิดใช้งาน downlevelIteration เป็นเรื่องง่าย แต่ถ้าคุณตั้งเป้าเป็น ES5/ES3 คุณอาจต้องวัดประสิทธิภาพเพื่อให้แน่ใจว่าการสนับสนุน iterator ไม่ส่งผลกระทบต่อประสิทธิภาพ (ถ้ามี ผลกระทบ คุณอาจใช้วิธีการแปลงด้วย Array.from หรือ forEach หรือวิธีแก้ปัญหาอื่น ๆ จะดีกว่า)
คำตอบ #7
นี่ใช้ได้ผลสำหรับฉัน
Object.keys(myMap).map( key => {
console.log("key: " + key);
console.log("value: " + myMap[key]);
});
คำตอบ #8
คุณยังสามารถใช้วิธี array map กับ iterable ของ Map.entries() ได้ด้วย:
[...myMap.entries()].map(
([key, value]: [string, number]) => console.log(key, value)
);
นอกจากนี้ ตามที่ได้กล่าวไว้ในคำตอบอื่น ๆ คุณอาจต้องเปิดใช้งานการวนซ้ำระดับต่ำในไฟล์ tsconfig.json ของคุณ (ภายใต้ตัวเลือกตัวคอมไพเลอร์):
"downlevelIteration": true,
