perks/object-comparison/main.ts

61 строка
2.0 KiB
TypeScript
Исходник Обычный вид История

2018-11-21 00:13:47 +03:00
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
2019-08-28 22:35:50 +03:00
function isPrimitive(object: any) {
switch (typeof object) {
case 'undefined':
case 'boolean':
case 'number':
case 'string':
case 'symbol':
return true;
default:
return false;
}
}
2019-11-05 01:54:42 +03:00
function _areSimilar(a: any, b: any, exceptionListSet: Set<string>): boolean {
// 100% similar things, including primitives
2018-11-21 00:13:47 +03:00
if (a === b) {
return true;
}
2018-11-21 00:13:47 +03:00
// typeof null is object, but if both were null that would have been already detected.
2019-11-05 01:54:42 +03:00
if (
a === null || b === null || // either is null?
isPrimitive(a) || isPrimitive(b) || // either is primitive
typeof a !== typeof b || // types not the same?
(Array.isArray(a) && !Array.isArray(b)) || // one an array and not the other?
(!Array.isArray(a) && Array.isArray(b))) {
return false;
}
2018-11-21 00:13:47 +03:00
// Object similarity is determined by the same set of keys NOT in
// the exception list (although not necessarily the same order), and equivalent values for every
// corresponding key NOT in the exception list.
2018-11-21 00:13:47 +03:00
2019-11-05 01:54:42 +03:00
// the same set of keys, but not neccesarily same order
const keysA = Object.keys(a).filter(each => !exceptionListSet.has(each)).sort();
const keysB = Object.keys(b).filter(each => !exceptionListSet.has(each)).sort();
2019-11-05 01:54:42 +03:00
if (keysA.length !== keysB.length) {
return false;
}
2018-11-21 00:13:47 +03:00
// key test
for (let i = keysA.length - 1; i >= 0; i--) {
if (keysA[i] !== keysB[i]) {
return false;
2018-11-21 00:13:47 +03:00
}
}
2019-11-05 01:54:42 +03:00
// value test
return !(keysA.find(key => !_areSimilar(a[key], b[key], exceptionListSet)));
2018-11-21 00:13:47 +03:00
}
2019-11-05 01:54:42 +03:00
export function areSimilar(a: any, b: any, ...exceptionList: Array<string>): boolean {
return _areSimilar(a, b, new Set(exceptionList));
}