Ben*_*aum 30 javascript equality map ecmascript-harmony
我正在尝试使用新的(ES6)Map对象来表示属性和值之间的映射.
我有类似于以下形式的对象:
{key1:value1_1,key2:value2_1},..... {key1:value1_N,key2:value2_N}
Run Code Online (Sandbox Code Playgroud)
我想根据key1 和 key2值对它们进行分组.
举例来说,我希望能够以组以下的x和y:
[{x:3,y:5,z:3},{x:3,y:4,z:4},{x:3,y:4,z:7},{x:3,y:1,z:1},{x:3,y:5,z:4}]
Run Code Online (Sandbox Code Playgroud)
并获取包含以下内容的Map:
{x:3,y:5} ==> {x:3,y:5,z:3},{x:3,y:5,z:4}
{x:3,y:4} ==> {x:3,y:4,z:4},{x:3,y:4,z:7}
{x:3,y:1} ==> {x:3,y:1,z:1}
Run Code Online (Sandbox Code Playgroud)
在Python中,我使用元组作为字典键.ES6映射允许任意对象作为键,但使用标准相等算法(===),因此对象只能通过引用来区分我所知道的.
如何使用ES6地图完成这种分组?或者,如果有一种我忽略的优雅方式,使用普通JS对象的解决方案.
我宁愿不使用外部集合库 - 但如果有一个更好的解决方案使用我也有兴趣了解它.
Ben*_*aum 18
好吧,我现在提出了关于es escucuss的问题,我得到了Mozilla的Jason Orendorff的回答:
.equals,.hashCode但是它被拒绝而不是有价值的对象.(我认为有充分理由).Bradley在ESDiscuss主题上提供了一个基本的集合(概念,不要在生产代码中使用),可能看起来像这样:
function HashMap(hash) {
var map = new Map;
var _set = map.set;
var _get = map.get;
var _has = map.has;
var _delete = map.delete;
map.set = function (k,v) {
return _set.call(map, hash(k), v);
}
map.get = function (k) {
return _get.call(map, hash(k));
}
map.has = function (k) {
return _has.call(map, hash(k));
}
map.delete = function (k) {
return _delete.call(map, hash(k));
}
return map;
}
function TupleMap() {
return new HashMap(function (tuple) {
var keys = Object.keys(tuple).sort();
return keys.map(function (tupleKey) { // hash based on JSON stringification
return JSON.stringify(tupleKey) + JSON.stringify(tuple[tupleKey]);
}).join('\n');
return hashed;
});
}
Run Code Online (Sandbox Code Playgroud)
更好的解决方案是使用MontageJS/Collections之类的东西,它允许指定hash/equals函数.
您可以在此处查看API文档.
这似乎不太方便.你能做什么?像往常一样可怕的东西.
let tuple = (function() {
let map = new Map();
function tuple() {
let current = map;
let args = Object.freeze(Array.prototype.slice.call(arguments));
for (let item of args) {
if (current.has(item)) {
current = current.get(item);
} else {
let next = new Map();
current.set(item, next);
current = next;
}
}
if (!current.final) {
current.final = args;
}
return current.final;
}
return tuple;
})();
Run Code Online (Sandbox Code Playgroud)
瞧.
let m = new Map();
m.set(tuple(3, 5), [tuple(3, 5, 3), tuple(3, 5, 4)]);
m.get(tuple(3, 5)); // [[3, 5, 3], [3, 5, 4]]
Run Code Online (Sandbox Code Playgroud)