使用Array对象作为ES6 Map的键

时间:2015-09-18 20:05:30

标签: javascript arrays dictionary ecmascript-6 es6-map

我正在尝试将我的代码更新为ES6,因为我使用的是Node 4.0,并且到目前为止它非常喜欢它的功能。但是,我对新的ES6 {}数据结构存在问题,因为当使用Array作为键时,它与Map的行为不同。我将它用作计数器图。

我运行此代码,我想知道如何使用数组作为"use strict"; var a = new Map(); a.set(['x','y'], 1); console.log(a.get(['x','y'])); var b = {}; b[['x','y']] = 1; console.log(b[['x','y']]); 的键。

1

打印出以下内容,第一行应为undefined而不是undefined 1

Map

原始的JS地图将字符串化,我不想使用新的ES6 Map执行相同类型的stringify hack。

如何将数组作为密钥可靠地用于ES6 children()

,我该怎么办?

3 个答案:

答案 0 :(得分:9)

了解ES2015 Map键与===运算符进行比较。两个数组实例,即使它们包含相同的值,也不会相互比较为===

试试这个:

var a = new Map(), key = ['x', 'y'];
a.set(key, 1);
console.log(a.get(key));

由于Map类可用作基类,因此可以实现具有覆盖.get()函数的子类。

答案 1 :(得分:2)

您需要保存对用作键的Array非原始实例的引用。请注意以下两个示例中的区别:

"use strict";

var a = new Map();
a.set(['x','y'], 1);
console.log(a.get(['x','y']));
console.log(['x','y'] === ['x','y']);

var b = new Map();
var array = ['x','y'];
b.set(array, 1);
console.log(b.get(array));
console.log(array === array);

答案 2 :(得分:0)

我也有此需要,因此我编写了一个ISC许可的库:array-keyed-map。您可以find it on npm。我认为the source很清楚,但是对于后代来说,这就是它的工作方式:


维护一个Map对象的树。每棵树都存储:

  • 在内部声明的Symbol键下:树中该点的值(如果有)。 Symbol保证了唯一性,因此用户提供的值都不能覆盖此密钥。

  • 在所有其他键上:到目前为止,所有其他已设置的下一棵树。

例如,在akmap.set(['a', 'b'], true)上,内部树结构将类似于-

'a':
  [value]: undefined
  'b':
    [value]: true

在此之后执行akmap.set(['a'], 'okay')只会更改'a'处路径的值:

'a':
  [value]: 'okay'
  'b':
    [value]: true

要获取数组的值,请遍历数组,同时从树上读取相应的键。如果树在任何时候都不存在,则返回undefined。最后,从您要到达的树上读取内部声明的[value]符号。

要删除数组的值,请执行相同的操作,但删除[value]-symbol-key下的任何值,如果递归步骤以size结尾,则在递归步骤之后删除所有子树。为0。


为什么要树?因为当多个数组具有相同的前缀时这非常有效,这在实际使用中非常典型,例如用于文件路径。