2つのES2015マップオブジェクトに同じ(key, value)
ペアのセットがあるかどうかを確認するにはどうすればよいですか?
すべてのキーと値はプリミティブデータ型であると想定できます。
これを解決するための1つのアプローチはmap.entries()
、を取得し、そこから配列を作成し、その配列をキーでソートすることです。他のマップでも同じことを行います。次に、これら2つの配列をループして比較します。これらすべてのシームは煩雑であり、並べ替え(パフォーマンスの非効率性)と配列の作成(メモリの非効率性)のために非常に非効率的です。
誰かがより良いアイデアを持っていますか?
これを行う「標準」または「組み込み」の方法はありません。概念的には、2つのMapオブジェクトが同じキーと各キーの値を持ち、追加のキーがないことを比較するだけです。
比較をできるだけ効率的にするために、次の最適化を行うことができます。
.size
、両方の地図でプロパティを確認します。2つのマップに同じ数のキーがない場合、すぐにわかるように、それらを同一にすることはできません。for (var [key, val] of map1)
自分でキーの配列を作成またはソートする必要がないように、イテレータ構文を使用してキーを反復します(より高速で、よりメモリ効率が良いはずです)。次に、undefined
はMapの正当な値.get()
ですが、キーが見つからない場合に返される値でもあるため、.has()
比較している値がである場合は、追加の処理を行うことでそれを監視する必要がありundefined
ます。
Mapオブジェクトのキーと値の両方がオブジェクト自体になる可能性があるため、===
Javascriptがデフォルトで同じオブジェクトをテストするために使用する単純なものだけでなく、オブジェクトの深いプロパティ比較で同等性を判断する場合、これははるかにトリッキーになります。または、キーと値のプリミティブを持つオブジェクトのみに関心がある場合は、この複雑さを回避できます。
厳密な値の等価性のみをテストする関数(オブジェクトをチェックして、オブジェクトが同じ物理オブジェクトであるかどうかを確認します。プロパティの詳細な比較ではありません)の場合、以下に示す方法を実行できます。これは、マップオブジェクトの効率的な反復にES6構文を使用false
し、不一致が見つかるとすぐに短絡して戻り、一致しない場合にパフォーマンスを改善しようとします。
"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);
}
値がオブジェクトまたは配列である可能性がある物理的に同じオブジェクトであるかどうかを比較するだけではなく、深いオブジェクト比較を実行したい場合、人生ははるかに複雑になります。
これを行うには、以下のすべてを考慮したディープオブジェクト比較メソッドが必要です。
Date
。深いオブジェクト比較(ここではStackOverflowでの投票数の多い回答を含む)の方法については他にもたくさん書かれているので、それはあなたの質問の主要な部分ではないと思います。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加