const hasOwnProperty = Object.prototype.hasOwnProperty; const isArray = Array.isArray; const keyList = Object.keys; const hasProp = Object.prototype.hasOwnProperty; /* Really simple clone utility. Only copies plain arrays, objects, and Dates. Transfers everything else as-is. Wanted to use a third-party lib, but none did exactly this. */ export function deepCopy(input) { if (Array.isArray(input)) { return input.map(deepCopy); } else if (input instanceof Date) { return new Date(input.valueOf()); } else if (typeof input === 'object' && input) { // non-null object return mapHash(input, deepCopy); } else { // everything else (null, function, etc) return input; } } function mapHash(input, func) { const output = {}; for (const key in input) { if (hasOwnProperty.call(input, key)) { output[key] = func(input[key], key); } } return output; } export function deepEqual(a, b) { if (a === b) { return true; } // tslint:disable-next-line: triple-equals if (a && b && typeof a == 'object' && typeof b == 'object') { const arrA = isArray(a); const arrB = isArray(b); let i: number; let length: number; let key: any; if (arrA && arrB) { length = a.length; // tslint:disable-next-line: triple-equals if (length != b.length) { return false; } for (i = length; i-- !== 0; ) { if (!deepEqual(a[i], b[i])) { return false; } } return true; } // tslint:disable-next-line: triple-equals if (arrA != arrB) { return false; } const dateA = a instanceof Date; const dateB = b instanceof Date; // tslint:disable-next-line: triple-equals if (dateA != dateB) { return false; } if (dateA && dateB) { // tslint:disable-next-line: triple-equals return a.getTime() == b.getTime(); } const regexpA = a instanceof RegExp; const regexpB = b instanceof RegExp; // tslint:disable-next-line: triple-equals if (regexpA != regexpB) { return false; } if (regexpA && regexpB) { // tslint:disable-next-line: triple-equals return a.toString() == b.toString(); } const keys = keyList(a); length = keys.length; if (length !== keyList(b).length) { return false; } for (i = length; i-- !== 0; ) { if (!hasProp.call(b, keys[i])) { return false; } } for (i = length; i-- !== 0; ) { key = keys[i]; if (!deepEqual(a[key], b[key])) { return false; } } return true; } return a !== a && b !== b; }