使用 Array 对象作为 ES6 Map 的键
Using Array objects as key for 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']]);
它打印出以下内容,第一行应该是 1
而不是 undefined
:
undefined
1
原始 JS 映射将键字符串化,我不想使用新的 ES6 Map
进行相同类型的字符串化破解。
如何使用数组作为 ES6 的可靠键 Map
?
了解 ES2015 映射键(几乎)与 ===
运算符进行比较。两个数组实例,即使它们包含相同的值,也永远不会相互比较 ===
。
试试这个:
var a = new Map(), key = ['x', 'y'];
a.set(key, 1);
console.log(a.get(key));
由于地图 class 旨在用作基础 class,您可以实现具有覆盖 .get()
功能的子class,也许。
(第一句中的"almost"是为了反映Map key的相等性比较是通过Object.is()
来完成的,这在日常编码中并不多见。它本质上是一个第三个 JavaScript 中平等测试的变体。)
您需要保存对用作键的 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);
我也有这个需求,所以我写了一个 ISC 许可的库:array-keyed-map. You can find it on npm. I think 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
要获取数组的值,请在从树中读取相应键的同时遍历数组。 Return undefined
如果树在任何一点都不存在。最后,从您到达的树中读取内部声明的 [value]
符号。
要删除数组的值,执行相同操作但删除 [value]
-symbol-key 下的任何值,并在递归步骤后删除任何以 [=21 结尾的子树=] 的 0.
为什么是一棵树?因为当多个数组具有相同的前缀时它非常有效,这在实际使用中非常典型,例如文件路径。
如果有人在这里寻找更基本的方法,您可以将自定义的键到字符串的一对一转换应用,例如 ${x}_${y}
(依赖于键的特定结构)或JSON.stringify(key)
(更通用)- 这绝不是一个完美的解决方案,但在许多情况下它可能是最可靠的。
我知道 OP 要求其他方法,但我认为这里仍然需要提及这个方法作为标题问题的最直接答案。
我正在尝试将我的代码更新为 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']]);
它打印出以下内容,第一行应该是 1
而不是 undefined
:
undefined
1
原始 JS 映射将键字符串化,我不想使用新的 ES6 Map
进行相同类型的字符串化破解。
如何使用数组作为 ES6 的可靠键 Map
?
了解 ES2015 映射键(几乎)与 ===
运算符进行比较。两个数组实例,即使它们包含相同的值,也永远不会相互比较 ===
。
试试这个:
var a = new Map(), key = ['x', 'y'];
a.set(key, 1);
console.log(a.get(key));
由于地图 class 旨在用作基础 class,您可以实现具有覆盖 .get()
功能的子class,也许。
(第一句中的"almost"是为了反映Map key的相等性比较是通过Object.is()
来完成的,这在日常编码中并不多见。它本质上是一个第三个 JavaScript 中平等测试的变体。)
您需要保存对用作键的 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);
我也有这个需求,所以我写了一个 ISC 许可的库:array-keyed-map. You can find it on npm. I think 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
要获取数组的值,请在从树中读取相应键的同时遍历数组。 Return undefined
如果树在任何一点都不存在。最后,从您到达的树中读取内部声明的 [value]
符号。
要删除数组的值,执行相同操作但删除 [value]
-symbol-key 下的任何值,并在递归步骤后删除任何以 [=21 结尾的子树=] 的 0.
为什么是一棵树?因为当多个数组具有相同的前缀时它非常有效,这在实际使用中非常典型,例如文件路径。
如果有人在这里寻找更基本的方法,您可以将自定义的键到字符串的一对一转换应用,例如 ${x}_${y}
(依赖于键的特定结构)或JSON.stringify(key)
(更通用)- 这绝不是一个完美的解决方案,但在许多情况下它可能是最可靠的。
我知道 OP 要求其他方法,但我认为这里仍然需要提及这个方法作为标题问题的最直接答案。