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};