Luk*_*uka 15 javascript dictionary
如何检查两个ES2015 Map对象是否具有相同的(key, value)对?
我们可以假设所有键和值都是原始数据类型.
解决此问题的一种方法是从中获取map.entries(),创建数组,然后按键对该数组进行排序.并与其他地图做同样的事情.然后遍历这两个数组来比较它们.由于排序(性能低效)以及制造这些阵列(内存效率低),所有这些接缝都很麻烦并且效率也非常低.
有没有人有更好的主意?
jfr*_*d00 24
没有"标准"或"内置"方式来做到这一点.从概念上讲,您只需比较两个Map对象对每个键具有相同的键和值,并且没有额外的键.
为了尽可能高效地进行比较,您可以执行以下优化:
.size在两张地图上查看酒店.如果两张地图的密钥数量不同,那么您就知道它们不能完全相同. for (var [key, val] of map1)迭代器语法来迭代键,这样您就不必自己构建或排序键组(应该更快,更高效).然后,因为它undefined是Map中的合法值,但是.get()如果找不到键也会返回,如果.has()我们要比较的值是,我们必须通过做额外的来注意undefined.
由于具有Map对象的键和值都可以是对象本身,如果您希望对对象进行深度属性比较以确定相等性,而不仅仅是===Javascript默认用于测试同一对象的更简单,那么这会变得非常棘手.或者,如果您只对具有键和值的基元的对象感兴趣,则可以避免这种复杂性.
对于仅测试严格值相等的函数(检查对象以查看它们是否是相同的物理对象,而不是深度属性比较),您可以执行下面显示的操作.这使用ES6语法有效地迭代地图对象,并尝试通过短路匹配来提高性能,并在发现不匹配时false立即返回.
此代码段需要Firefox 41或Chrome 49.它在Edge 25或IE 11中不起作用(可能是因为for/of它正在使用的ES6语法类型的用户).它可以通过使用旧技术用于for循环在其他浏览器中工作,但由于这已经是关于ES6功能(Map对象),我们正在尝试优化实现,我选择使用最新的ES6语法.
"use strict";
function compareMaps(map1, map2) {
var testVal;
if (map1.size !== map2.size) {
return false;
}
for (var [key, val] of map1) {
testVal = map2.get(key);
// in cases of an undefined value, make sure the key
// actually exists on the object so there are no false positives
if (testVal !== val || (testVal === undefined && !map2.has(key))) {
return false;
}
}
return true;
}
// construct two maps that are initially identical
var o = {"k" : 2}
var m1 = new Map();
m1.set("obj", o);
m1.set("str0", undefined);
m1.set("str1", 1);
m1.set("str2", 2);
m1.set("str3", 3);
var m2 = new Map();
m2.set("str0", undefined);
m2.set("obj", o);
m2.set("str1", 1);
m2.set("str2", 2);
m2.set("str3", 3);
log(compareMaps(m1, m2));
// add an undefined key to m1 and a corresponding other key to m2
// this will pass the .size test and even pass the equality test, but not pass the
// special test for undefined values
m1.set("str-undefined", undefined);
m2.set("str4", 4);
log(compareMaps(m1, m2));
// remove one key from m1 so m2 has an extra key
m1.delete("str-undefined");
log(compareMaps(m1, m2));
// add that same extra key to m1, but give it a different value
m1.set("str4", 5);
log(compareMaps(m1, m2));
function log(args) {
var str = "";
for (var i = 0; i < arguments.length; i++) {
if (typeof arguments[i] === "object") {
str += JSON.stringify(arguments[i]);
} else {
str += arguments[i];
}
}
var div = document.createElement("div");
div.innerHTML = str;
var target = log.id ? document.getElementById(log.id) : document.body;
target.appendChild(div);
}Run Code Online (Sandbox Code Playgroud)
如果你想进行深度对象比较,而不是仅仅比较它们是否在物理上是同一个对象,其中值可以是对象或数组,那么生活会变得复杂得多.
要做到这一点,您需要一个深度对象比较方法,该方法考虑以下所有因素:
Date.由于在其他地方写了很多关于如何进行深度对象比较(包括StackOverflow上的一些高度评价的答案),我将假设这不是你问题的主要部分.
小智 8
这是一个用于检查映射相等性的单行函数:
const mapsAreEqual = (m1, m2) => m1.size === m2.size && Array.from(m1.keys()).every((key) => m1.get(key) === m2.get(key));
Run Code Online (Sandbox Code Playgroud)