首页 > 解决方案 > 如何遍历 Typescript 中的地图:for...in?为了……的?为每个?

问题描述

我试图了解在 Typescript 中迭代地图的语法。我的地图中的键是字符串。这些值是字符串数组。

这是一些示例代码:

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");

当我运行这段代码时,唯一打印的是“完成”。

为什么地图中没有任何内容被打印出来,“我们在地图中”的消息也没有?就好像永远不会进入 for 循环一样。为什么会这样,我将如何解决这个问题?

标签: javascripttypescriptdictionaryfor-loop

解决方案


当您将键设置为 Map 时,键不会被放入 Map 实例中 - 它们存储在 Map内部,并且只能通过使用各种 Map 迭代方法之一来访问。仅直接在对象或其原​​型上for..in迭代属性。

要遍历 Map,请尝试以下操作:

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

for..in当您的集合是一个在对象本身上具有键值对的普通对象时才有意义,但不适用于以不同方式存储数据的 Maps。

当属性直接位于对象上时,语法通常如下所示:

someObj.someProp = 'someVal';

这会将someProp属性放到someObj对象上。

但是地图将其数据存储在地图的 [[MapData]]内部槽中,而不是直接存储在地图的不同属性上。

就像一个理论练习一样,在 JS 中,您可以将属性直接放在 Map 实例上,然后它会被迭代for..in(基本上,滥用地图作为具有自身属性的对象):

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

但这是一种反模式,永远不应该这样做。要么使用对象并使用点和括号表示法(以及其他对象方法,如Object.entries)来设置/检索属性,或者使用 Map 并使用Map.getandMap.set和其他 Map 方法设置/检索属性。


推荐阅读