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 beta 5とTypeScript 1.8.10を使用していますが、私の目標はes 5です。誰もがこの問題を抱えていますか?
代わりにMap.prototype.forEach((value, key, map) => void, thisArg?) : void
を使うことができます
このように使用してください。
myMap.forEach((value: boolean, key: string) => {
console.log(key, value);
});
Array.from()メソッドを使ってそれをArrayに変換するだけです。
myMap : Map<string, boolean>;
for(let key of Array.from( myMap.keys()) ) {
console.log(key);
}
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]));
これは私のために働きました。 TypeScriptバージョン:2.8.3
for (const [key, value] of Object.entries(myMap)) {
console.log(key, value);
}
for (let entry of Array.from(map.entries())) {
let key = entry[0];
let value = entry[1];
}
TypeScript 2.3リリースノートの "New --downlevelIteration
" によると、
ES5/E3では、
for..of statements
の使用時に、--downlevelIteration
、Array Destructuring、およびArray、Call、New式のSpread要素でSymbol.iteratorがサポートされています。
これはデフォルトでは有効になっていません!イテレータを完全にサポートするために、"downlevelIteration": true
にtsconfig.json
を追加するか、--downlevelIteration
フラグをtsc
に渡してください。
これで、for (let keyval of myMap) {...}
と書くことができ、keyval
の型は自動的に推測されます。
なぜこれがデフォルトでオフになっているのですか? TypeScriptの貢献者によると @ aluanhaddad 、
これはオプションです。これは、(配列を含む)すべての反復可能オブジェクトの使用において、生成コードのサイズ、および場合によってはパフォーマンスに非常に大きな影響を与えるためです。
ES2015("target": "es2015"
またはtsconfig.json
内のtsc --target ES2015
)以降をターゲットにできる場合は、downlevelIteration
を有効にすることは非常に簡単ですが、ES5/ES3をターゲットにする場合は、イテレータサポートがパフォーマンスに影響しないようにベンチマークすることArray.from
変換やforEach
、あるいはその他の回避策を使ったほうがいいかもしれません)。
私は最新のTSとノード(それぞれv2.6とv8.9)を使っています。
let myMap = new Map<string, boolean>();
myMap.set("a", true);
for (let [k, v] of myMap) {
console.log(k + "=" + v);
}
これは私のために働きました。
Object.keys(myMap).map( key => {
console.log("key: " + key);
console.log("value: " + myMap[key]);
});
あなたがタイプ(キー、配列)のマップを持っているならHTMLからそれをするためのちょうど簡単な説明:
このようにして配列を初期化します。
public cityShop: Map<string, Shop[]> = new Map();
そしてそれを繰り返すために、私はキーの値から配列を作成します: - 単に配列としてそれを使用します:keys = Array.from(this.cityShop.keys())
それから、HTMLでは、私は使用することができます:
*ngFor="let key of keys"
この枠の中では、this.cityShop.get(key)で配列の値を取得しています。
そして…やった!
入れ子関数があまり好きではない場合は、キーを反復処理することもできます。
myMap : Map<string, boolean>;
for(let key of myMap) {
if (myMap.hasOwnProperty(key)) {
console.log(JSON.stringify({key: key, value: myMap[key]}));
}
}
注意してください、あなたがhasOwnProperty
で非キー反復を除外しなければならない、これをしないならば、あなたは警告またはエラーを得ます。