【问题标题】:Javascript Map orderingJavascript 地图排序
【发布时间】:2018-04-27 19:19:52
【问题描述】:

我最近在我的代码中遇到了一个错误,这是由于我在查看 MDN 上的地图对象详细信息时缺少“按插入顺序”文本。简而言之,我有一个地图对象,可以说

let myMap = new Map;

然后,在填充它之后,我用一个简单的 for .. of 语句迭代它的内容。像这样

for (let [key, val] of myMap) { 
    ...
}

for 循环中的代码依赖于 (key, value) 对,按 key 排序。但是,填充地图的算法是以随机顺序执行的(我无法更改)。为了解决这个问题,我现在首先将所有可能的键添加到地图对象中,如下所示:

let myMap = new Map;
for (let i=0; i<maxkey; ++i) myMap.set(key(i), undefined);

// And in the for loop
for (let [key, val] of myMap) {
    if (typeof val === "undefined") continue;
    //...
}

幸运的是,它们并不多(因此性能损失可以忽略不计),这很有效。这个解决方案对我来说还是有点尴尬。

还有更好的吗?

【问题讨论】:

  • 将其转换为数组并排序。 [...map].sort(([k1], [k2]) =&gt; k1.localeCompare(k2))
  • 数组类型为 [{key: T, value: V}],然后是 arr.sort((a, b) => compare(a.key, b.key)) ?
  • 我猜是的,这是一个选项

标签: javascript es6-map


【解决方案1】:

映射中键的顺序取决于映射实现。具有自然排序键的映射通常称为树映射,因为键存储在tree 中。我没有在 JS 中使用树形图,所以我不能推荐一个特定的实现。

【讨论】:

    【解决方案2】:

    for循环中的代码依赖(key, value)对进行key排序。

    那么Map 对您来说是错误的数据结构。它的目的是快速查找,而不是维护顺序。如果您需要有序(可排序)序列,请使用数组。或者,如果您需要查找和自定义订单,则将两者结合使用。对于具有少量已知键的特定情况,预填充映射很好,或者仅将它们用于迭代

    for (let key=0; key < maxkey; key++) {
        if (myMap.has(key)) {
            const val = myMap.get(key);
            … // use key and value
        }
    }
    

    或者如果键的数量比存储在地图中的多,你也可以这样做

    for (const key of Array.from(myMap.keys()).sort((a, b) => a-b)) {
        const val = myMap.get(key);
        … // use key and value
    }
    

    如果您必须多次执行此操作,您可能还需要实现自己的迭代器。

    【讨论】:

    • 地图维护一个顺序,插入的顺序。你想说的是地图不会保持排序。数组的顺序与映射相同,除非您明确使用sort 方法。
    • @DavidCallanan 是的,这就是我的意思 - 地图无法重新排序。即使他们确实使用固定顺序来保持一致性,但被排序并不是他们的主要目的。
    【解决方案3】:

    根据mozilla javascript参考here

    一个 Map 对象按照条目的顺序迭代条目、键和值 插入。

    因此您应该在将键插入映射之前对其进行排序,然后您可以按键顺序迭代映射。

    【讨论】:

      猜你喜欢
      • 2011-06-15
      • 2014-02-01
      • 2020-04-22
      • 2015-06-06
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 2013-01-16
      • 1970-01-01
      相关资源
      最近更新 更多