如何迭代一个Map()对象?

11
我有一个Map()对象,我需要迭代它,以便可以获取星期几和选择的小时。下面的代码不起作用,因为Object.keys(newFieldReservationPrice).forEach试图循环一个Map()对象,这似乎没有意义。那么,有没有更好的解决方案呢?
以下是代码:
handlePriceInput = (e, hour, day) => {
let value = e.target.value

const newFieldReservationPrice = this.state.newFieldReservationPrice
console.log('newFieldReservationPrice', newFieldReservationPrice) // A Map();
let map;

if (!newFieldReservationPrice instanceof Map) {
  console.log('!== Map')
  console.log('newFieldReservationPrice is a Map()? inside if ()', newFieldReservationPrice)
  if (newFieldReservationPrice[day] && newFieldReservationPrice[day][hour]) {
      newFieldReservationPrice[day][hour] = Number(value)
  } 
} else {
  map = new Map();
  console.log('map object', Object.keys(newFieldReservationPrice)) // logs map object []

  Object.keys(newFieldReservationPrice).forEach(key => {
    console.log('key', key)
      map.set(key, new Map(Object.entries(newFieldReservationPrice[key])));
  }); // This doesn't work
  console.log('Am I a Map()? map', map)

  const aux = map.get(day)
  console.log('aux day', aux) // A Map()
  aux.set(hour, Number(value)) // Comes as undefined || Cannot read property 'set' of undefined
  console.log('aux set', aux) // A Map()

  map.set(day, aux);
  console.log('what do I have?', map)
  
}
const isReservationPrice = !newFieldReservationPrice instanceof Map ? newFieldReservationPrice : map
console.log('isReservationPrice', isReservationPrice)

this.setState({
  newFieldReservationPrice: isReservationPrice
})
}

请参考以下链接,了解有关JavaScript中Map对象的forEach方法的详细信息:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach - Vaibhav Vishal
1
可能是重复问题:https://dev59.com/zlYN5IYBdhLWcg3wopaw#47136047。虽然不完全相同,但不标记为重复。 - Rajesh
3个回答

19

Map提供了三种获取其内容迭代器的方式:

  • keys - 迭代映射中的键
  • values - 迭代值
  • entries - 迭代键和值,给出 [key, value] 数组(这是默认设置)

正如 Nina 所指出的那样, Map 还提供了 forEach,它循环遍历其内容,并将回调作为参数传递给值、键和映射。

根据您的用例选择适当的方法。例如,如果您想替换 Object.keys,请使用 keys。同样,如果您想要映射中的条目(我注意到您在某个地方使用了 Object.entries),请使用 entries 或默认迭代器。

注意,在您的代码中,有几个地方似乎尝试使用[]来索引映射。这对于映射是无效的,您需要使用get
以下是使用默认迭代器(也是从entries获取的迭代器)的简单示例:

const map = new Map();
map.set(1, "one");   // Could also include these when calling
map.set(2, "two");   // the constructor but I wanted to
map.set(3, "three"); // avoid any confusion

for (const [key, value] of map) { // Using the default iterator (could be `map.entries()` instead)
    console.log(`The value for key ${key} is ${value}`);
}


还要注意,如果你在设置新状态时基于现有状态而不使用回调版本的setState,那么你正在违反React的规则之一。如果需要在设置新状态时使用现有状态,你必须使用回调版本:

this.setState(prevState => {
    // ...use `prevState` values (*not* `this.state`!) to create an object with
    // the updates, then return the object...
});

谢谢您的解释。您的意思是类似于 map.set(key, new Map(Object.entries(newFieldReservationPrice.get(key)))) 这样吗? - RCohen
@RCohen - 你想用 new Map(Object.entries(newFieldReservationPrice.get(key))) 做什么? - T.J. Crowder
就像你所说的,将[key]索引到映射中是行不通的。因此,这里的想法是:
  • 星期一:
    • 08:00:10(在这一天和小时存储10)
获取日期和小时,在这种情况下为08:00,以保存新值。使用newFieldReservationPrice.forEach迭代小时。
- RCohen
@RCohen - 是的,但你为什么要从结果创建一个Map呢?但是,我是指使用newFieldReservationPrice.get(key)而不是newFieldReservationPrice[key]。对我来说,这是剩下的部分让我感到困惑,因为它假设存储在newFieldReservationPrice中的值不是映射(因为它使用了Object.entries),但是你正在将Map设置为newFieldReservationPrice中的值。 - T.J. Crowder
这是因为这些数据来自数据库作为一个对象,我需要将其作为Map发送回去。这就是我这样做的原因。这是我找到的一种方法,也许不是最好的方法。@T.J Crowder - RCohen
显示剩余2条评论

15
您可以使用 for of 来迭代一个 Map 对象:
for (const [key, value] of myMap) {
  console.log(key, value);
}

这与遍历条目相同:

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

正如 @Nina Scholz 所说,您可以在 Map 原型上使用 forEachMDN 文档):

myMap.forEach((value, key, map) => {
  console.log(key, value);
}

我不知道为什么 Object.entries(newFieldReservationPrice).forEach 对我不起作用。同样,Object.keys(newFieldReservationPrice).forEach也是如此。 - RCohen

5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接