【问题标题】:ES6 Map iteration costES6 地图迭代成本
【发布时间】:2015-09-22 15:23:54
【问题描述】:

我有一系列项目:var treeItems = [];treeItems.length 可能是 5-30(可能是 50),但每个 treeItem 都是相当大的对象。我应该两者都做:遍历项目并通过 id 获取项目。

我正在考虑用 es6 Map 替换数组。并遍历地图使用:Array.from(treeItemsMap.values()) 操作。

问题:Array.from(map.values()) 操作的成本(时间/内存)是多少?

附:我正在为移动设备做 SPA,因此内存使用量也很重要。

【问题讨论】:

  • 相当广泛的问题,但我不会使用 Array.from 进行迭代,因为您每次都会创建一个新数组 - for..of 可能更合适。您的 ID 是非连续的还是只是索引?
  • 为什么不只是像这样的数据结构 { tree_item_id : tree_item, ... }; O(1)
  • @elio.d 是的,这正是我想做的事
  • @RGraham 我的地图看起来像` { tree_item_id : tree_item, ... }`
  • 你可能会觉得这个jsPerf很有趣

标签: javascript dictionary ecmascript-6


【解决方案1】:

spec 说:

Map 对象必须使用哈希表或其他方法来实现 平均而言,提供次线性访问时间的机制 关于集合中元素的数量。

具体成本取决于实施。

使用Array.from 只会将数据复制到数组中,这会浪费内存。最好迭代地图。

注意50项是一个非常小的数据。我不认为在地图上有巨大的物体很重要。请记住 JS 是一种按值传递的语言,但在对象的情况下,该值是一个引用。所以地图将只包含 50 个对对象的引用,这些引用将单独存储。迭代或访问那个小地图应该不会花费太多。

【讨论】:

  • 你的意思是每个浏览器都有自己的实现吗?如果没有,我可以在哪里找到实现?
  • @V_B 是的,每个浏览器都有自己的实现。 ES 提出了一个实现,但是“本 Map 对象规范中使用的数据结构只是为了描述 Map 对象所需的可观察语义。它并不是一个可行的实现模型。”跨度>
  • @Oriol:ES 规范“提议”的“实现”不满足其复杂性约束。它实际上只用于定义可观察的语义。
  • @V_B:有很多开源的 js 引擎,如果你真的在乎,可以去看看。但是你几乎无法选择或改变你运行代码的那个,你不应该让你的代码依赖于实现——只需编写正确的代码。
【解决方案2】:

使用 .map() 迭代器的方法。

我们可以对 Maps 使用一个简单的技巧,因为 Maps 没有 map() 这样的操作。 Dr. Axel Rauschmayer建议: * 将映射转换为 [key,value] 对的数组。 * 映射或过滤数组。 * 将结果转换回地图。

例子:

let map0 = new Map([
  ["a", 1],
  ["b", 2],
  ["c", 3]
]);

const map1 = new Map(
  [...map0]
  .map(([k, v]) => ['_' + k, v * 2])
);

导致

{'_a' => 2, '_b' => 4, '_c' => 6}

【讨论】:

    【解决方案3】:

    使用 for(){...} 运算符的方法。

    我们可以像这样迭代 ES6 Map:

    let map0 = new Map([
      ["a", 1],
      ["b", 2],
      ["c", 3]
    ]);
    
    let map1 = new Map();
    for (let [key, value] of map0) {
        map1.set('_' + k, v * 2);    
    }
    

    导致

    {'_a' => 2, '_b' => 4, '_c' => 6}
    

    【讨论】:

      猜你喜欢
      • 2015-12-30
      • 1970-01-01
      • 1970-01-01
      • 2013-01-07
      • 1970-01-01
      • 1970-01-01
      • 2015-06-01
      • 2015-06-24
      • 2013-03-16
      相关资源
      最近更新 更多