You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.2 KiB

var collectionCompare = compare;
/*
primitives: value1 === value2
functions: value1.toString == value2.toString
arrays: if length, sequence and values of properties are identical
objects: if length, names and values of properties are identical
compare([[1, [2, 3]], [[1, [2, 3]]); // true
compare([[1, [2, 3], 4], [[1, [2, 3]]); // false
compare({a: 2, b: 3}, {a: 2, b: 3}); // true
compare({a: 2, b: 3}, {b: 3, a: 2}); // true
compare({a: 2, b: 3, c: 4}, {a: 2, b: 3}); // false
compare({a: 2, b: 3}, {a: 2, b: 3, c: 4}); // false
compare([[1, [2, {a: 4}], 4], [[1, [2, {a: 4}]]); // true
*/
function compare(value1, value2) {
if (value1 === value2) {
return true;
}
/* eslint-disable no-self-compare */
// if both values are NaNs return true
if (value1 !== value1 && value2 !== value2) {
return true;
}
if ({}.toString.call(value1) != {}.toString.call(value2)) {
return false;
}
if (value1 !== Object(value1)) {
// non equal primitives
return false;
}
if (!value1) {
return false;
}
if (Array.isArray(value1)) {
return compareArrays(value1, value2);
}
if ({}.toString.call(value1) == '[object Set]') {
return compareArrays(Array.from(value1), Array.from(value2));
}
if ({}.toString.call(value1) == '[object Object]') {
return compareObjects(value1, value2);
} else {
return compareNativeSubtypes(value1, value2);
}
}
function compareNativeSubtypes(value1, value2) {
// e.g. Function, RegExp, Date
return value1.toString() === value2.toString();
}
function compareArrays(value1, value2) {
var len = value1.length;
if (len != value2.length) {
return false;
}
var alike = true;
for (var i = 0; i < len; i++) {
if (!compare(value1[i], value2[i])) {
alike = false;
break;
}
}
return alike;
}
function compareObjects(value1, value2) {
var keys1 = Object.keys(value1).sort();
var keys2 = Object.keys(value2).sort();
var len = keys1.length;
if (len != keys2.length) {
return false;
}
for (var i = 0; i < len; i++) {
var key1 = keys1[i];
var key2 = keys2[i];
if (!(key1 == key2 && compare(value1[key1], value2[key2]))) {
return false;
}
}
return true;
}
export {collectionCompare as default};