简体   繁体   English

如何遍历 Typescript 中的 map:for...in? 为了……的? 为每个?

[英]How to iterate through a map in Typescript: for…in? for…of? forEach?

I am trying to understand the syntax for iterating through a map in Typescript.我试图了解在 Typescript 中迭代 map 的语法。 The keys in my map are strings.我的 map 中的键是字符串。 The values are arrays of strings.这些值为字符串的 arrays。

Here is some sample code:这是一些示例代码:

let attributeMap: Map<string, string[]> = new Map<string, string[]>();

// sample data
let sampleKey1 = "bob";

// populate map
let value: string[] = attributeMap.get(sampleKey1) || [];
value.push("clever");
attributeMap.set(sampleKey1, value);

value = attributeMap.get(sampleKey1) || [];
value.push("funny");
attributeMap.set(sampleKey1, value);


// try looping through the map
for (let key in attributeMap) {
    console.log(attributeMap.get(key));
    console.log("WE'RE IN THE MAP!");
}

console.log("done");

When I run this code, the only thing printed is "done".当我运行这段代码时,唯一打印的是“完成”。

Why is it that nothing in the map gets printed, nor does the message "WE'RE IN THE MAP"?为什么 map 中没有任何内容被打印,也没有“我们在地图中”的消息? It's as if the for loop is never entered.就好像永远不会进入 for 循环一样。 Why is that and how would I fix that?为什么会这样,我将如何解决这个问题?

When you set keys to Maps, the keys do not get put onto the Map instance - they're stored internally in the Map, and can only be accessed by using one of the various Map iteration methods.当您将密钥设置为 Maps 时,密钥不会被放入 Map 实例 - 它们内部存储在 Map 中,并且只能通过使用各种 Z46F3EA056CAA3126B91F3F70BEEA068C 迭代方法之一访问。 for..in only iterates over properties directly on an object or its prototypes. for..in直接在object 或其原型上迭代属性。

To iterate over the Map, try something like this instead:要遍历 Map,请尝试以下操作:

for (const [key, value] of attributeMap.entries()) {
  console.log(key, value);
}

for..in makes sense when your collection is a normal object with key-value pairs on the object itself, but not for Maps, which stores data differently.当您的集合是一个普通的 object 本身具有键值对的 object 时, for..in是有意义的,但不适用于以不同方式存储数据的 Maps。

When a property is directly on an object, the syntax will usually look something like this:当属性直接位于 object 上时,语法通常如下所示:

someObj.someProp = 'someVal';

This puts the someProp property onto the someObj object.这会将someProp属性放到someObj object 上。

But Maps store their data inside the [[MapData]] internal slot of the Map, and not directly on different properties of the Map.但是地图将其数据存储在 Map 的 [[MapData]]内部插槽中,而不是直接存储在 Map 的不同属性上。

Just as a theoretical exercise, in JS, you could put a property directly on a Map instance and it'll be iterated over with for..in (basically, abusing a map as an object with own-properties):就像理论练习一样,在 JS 中,您可以将属性直接放在 Map 实例上,然后用for..in对其进行迭代(基本上,将 map 滥用为 ZA8CFDE6331BD59EB2666F8911CB 拥有:

const map = new Map();
map.foo = 'bar';
for (const prop in map) {
  // ...
}

But that's quite an antipattern and should never be done.但这是一种反模式,永远不应该这样做。 Either use an object and set/retrieve properties with dot and bracket notation (and other object methods like Object.entries ), or use a Map and set/retrieve properties with Map.get and Map.set and the other Map methods. Either use an object and set/retrieve properties with dot and bracket notation (and other object methods like Object.entries ), or use a Map and set/retrieve properties with Map.get and Map.set and the other Map methods.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM