-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathareEquivalentObjects.js
51 lines (51 loc) · 1.67 KB
/
areEquivalentObjects.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*!
* @author electricessence / https://github.com/electricessence/
* Licensing: MIT
*/
import type from '@tsdotnet/type';
import areEqual from './areEqual';
/**
* Determines if two primitives are equal or if two objects have the same key/value combinations.
* @param a
* @param b
* @param nullEquivalency If true, null/undefined will be equivalent to an empty object {}.
* @param extraDepth
* @returns {boolean}
*/
export default function areEquivalentObjects(a, b, nullEquivalency = true, extraDepth = 0) {
// Take a step by step approach to ensure efficiency.
if (areEqual(a, b))
return true;
const aKeys = type.isObject(a) && Object.keys(a), bKeys = type.isObject(b) && Object.keys(b);
if (a == null || b == null) {
if (!nullEquivalency)
return false;
if (aKeys)
return !aKeys.length;
if (bKeys)
return !bKeys.length;
return a == null && b == null;
}
if (aKeys && bKeys) {
const len = aKeys.length;
if (len !== bKeys.length)
return false;
aKeys.sort();
bKeys.sort();
for (let i = 0; i < len; i++) {
const key = aKeys[i];
if (key !== bKeys[i] || !areEqual(a[key], a[key]))
return false;
}
// Doesn't track circular references but allows for controlling the amount of recursion.
if (extraDepth > 0) {
for (const key of aKeys) {
if (!areEquivalentObjects(a[key], a[key], nullEquivalency, extraDepth - 1))
return false;
}
}
return true;
}
return false;
}
//# sourceMappingURL=areEquivalentObjects.js.map