web-dev-qa-db-ja.com

TypeScriptマップの繰り返し

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です。誰もがこの問題を抱えていますか?

73
mwe

代わりにMap.prototype.forEach((value, key, map) => void, thisArg?) : voidを使うことができます

このように使用してください。

myMap.forEach((value: boolean, key: string) => {
    console.log(key, value);
});
113
rinukkusu

Array.from()メソッドを使ってそれをArrayに変換するだけです。

myMap : Map<string, boolean>;
for(let key of Array.from( myMap.keys()) ) {
   console.log(key);
}
27
6qat

Array.fromArray.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]));
14
Tobold

これは私のために働きました。 TypeScriptバージョン:2.8.3

for (const [key, value] of Object.entries(myMap)) { 
    console.log(key, value);
}
12
Debashish Sen
for (let entry of Array.from(map.entries())) {
    let key = entry[0];
    let value = entry[1];
}
9
Oded Breiner

TypeScript 2.3リリースノートの "New --downlevelIteration" によると、

ES5/E3では、for..of statementsの使用時に、--downlevelIteration、Array Destructuring、およびArray、Call、New式のSpread要素でSymbol.iteratorがサポートされています。

これはデフォルトでは有効になっていません!イテレータを完全にサポートするために、"downlevelIteration": truetsconfig.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、あるいはその他の回避策を使ったほうがいいかもしれません)。

8
Ahmed Fasih

私は最新の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);
}
4
lazieburd

これは私のために働きました。

Object.keys(myMap).map( key => {
    console.log("key: " + key);
    console.log("value: " + myMap[key]);
});
3
Jason Slobotski

あなたがタイプ(キー、配列)のマップを持っているならHTMLからそれをするためのちょうど簡単な説明:

このようにして配列を初期化します。

public cityShop: Map<string, Shop[]> = new Map();

そしてそれを繰り返すために、私はキーの値から配列を作成します: - 単に配列としてそれを使用します:keys = Array.from(this.cityShop.keys())

それから、HTMLでは、私は使用することができます:

*ngFor="let key of keys"

この枠の中では、this.cityShop.get(key)で配列の値を取得しています。

そして…やった!

1

入れ子関数があまり好きではない場合は、キーを反復処理することもできます。

myMap : Map<string, boolean>;
for(let key of myMap) {
   if (myMap.hasOwnProperty(key)) {
       console.log(JSON.stringify({key: key, value: myMap[key]}));
   }
}

注意してください、あなたがhasOwnPropertyで非キー反復を除外しなければならない、これをしないならば、あなたは警告またはエラーを得ます。

0
peterh