使用Array对象作为ES6 Map的键

jim*_*pez 11 javascript arrays dictionary ecmascript-6 es6-map

我正在尝试将我的代码更新为ES6,因为我使用的是Node 4.0,并且到目前为止它非常喜欢它的功能.但是我遇到了新的ES6 Map数据结构的问题,因为它与用作密钥{}时的行为不同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']]);
Run Code Online (Sandbox Code Playgroud)

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

undefined
1
Run Code Online (Sandbox Code Playgroud)

原始的JS映射将字符串化,我不想与新的ES6进行相同类型的stringify hack Map.

如何将数组作为ES6的可靠键使用Map

Mar*_*ski 12

如果有人在这里寻找更基本的方法,您可以应用键到字符串的自定义一对一转换,例如${x}_${y}(依赖于特定的键结构)或JSON.stringify(key)(更通用) - 这绝不是这是一个完美的解决方案,但在许多情况下它是最可靠的。

我知道OP要求其他方法,但我认为仍然需要在这里提到这个方法,作为对标题问题的最直接答案。


Poi*_*nty 10

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

试试这个:

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

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

  • 感谢您的详细回答,但覆盖 `.get()` 不是我想要做的 (2认同)

Ank*_*nko 7

我也有这个需求,所以我写了一个 ISC 许可的库:array-keyed-map。你可以在 npm 上找到它。我认为来源很清楚,但无论如何,这是它的工作原理,供后代使用:


维护Map对象树。每棵树存储:

  • 在内部声明的Symbol键下:树中该点的值(如果有)。在Symbol保证唯一性,所以没有用户提供的价值可以覆盖这个关键。

  • 在它的所有其他键上:所有其他到目前为止从这棵树设置下一个树。

例如,在 上akmap.set(['a', 'b'], true),内部树结构将是这样的——

'a':
  [value]: undefined
  'b':
    [value]: true
Run Code Online (Sandbox Code Playgroud)

akmap.set(['a'], 'okay')之后做只会改变路径的值'a'

'a':
  [value]: 'okay'
  'b':
    [value]: true
Run Code Online (Sandbox Code Playgroud)

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

要删除数组的值,请执行相同操作,但删除[value]-symbol-key下的所有值,并在递归步骤后删除所有子树,如果它们以 asize为 0结束。


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


Pat*_*rts 5

您需要保存对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);
Run Code Online (Sandbox Code Playgroud)