UNPKG

6.22 kBJavaScriptView Raw
1/*
2 * Copyright 2017 Palantir Technologies, Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16/* eslint-enable deprecation/deprecation */
17/**
18 * Returns true if the arrays are equal. Elements will be shallowly compared by
19 * default, or they will be compared using the custom `compare` function if one
20 * is provided.
21 */
22export function arraysEqual(arrA, arrB, compare) {
23 if (compare === void 0) { compare = function (a, b) { return a === b; }; }
24 // treat `null` and `undefined` as the same
25 if (arrA == null && arrB == null) {
26 return true;
27 }
28 else if (arrA == null || arrB == null || arrA.length !== arrB.length) {
29 return false;
30 }
31 else {
32 return arrA.every(function (a, i) { return compare(a, arrB[i]); });
33 }
34}
35/**
36 * Shallow comparison between objects. If `keys` is provided, just that subset
37 * of keys will be compared; otherwise, all keys will be compared.
38 *
39 * @returns true if items are equal.
40 */
41export function shallowCompareKeys(objA, objB, keys) {
42 // treat `null` and `undefined` as the same
43 if (objA == null && objB == null) {
44 return true;
45 }
46 else if (objA == null || objB == null) {
47 return false;
48 }
49 else if (Array.isArray(objA) || Array.isArray(objB)) {
50 return false;
51 }
52 else if (keys != null) {
53 return shallowCompareKeysImpl(objA, objB, keys);
54 }
55 else {
56 // shallowly compare all keys from both objects
57 var keysA = Object.keys(objA);
58 var keysB = Object.keys(objB);
59 return (shallowCompareKeysImpl(objA, objB, { include: keysA }) &&
60 shallowCompareKeysImpl(objA, objB, { include: keysB }));
61 }
62}
63/**
64 * Deep comparison between objects. If `keys` is provided, just that subset of
65 * keys will be compared; otherwise, all keys will be compared.
66 *
67 * @returns true if items are equal.
68 */
69export function deepCompareKeys(objA, objB, keys) {
70 if (objA === objB) {
71 return true;
72 }
73 else if (objA == null && objB == null) {
74 // treat `null` and `undefined` as the same
75 return true;
76 }
77 else if (objA == null || objB == null) {
78 return false;
79 }
80 else if (Array.isArray(objA) || Array.isArray(objB)) {
81 return arraysEqual(objA, objB, deepCompareKeys);
82 }
83 else if (isSimplePrimitiveType(objA) || isSimplePrimitiveType(objB)) {
84 return objA === objB;
85 }
86 else if (keys != null) {
87 return deepCompareKeysImpl(objA, objB, keys);
88 }
89 else if (objA.constructor !== objB.constructor) {
90 return false;
91 }
92 else {
93 var keysA = Object.keys(objA);
94 var keysB = Object.keys(objB);
95 if (keysA == null || keysB == null) {
96 return false;
97 }
98 if (keysA.length === 0 && keysB.length === 0) {
99 return true;
100 }
101 return arraysEqual(keysA, keysB) && deepCompareKeysImpl(objA, objB, keysA);
102 }
103}
104/**
105 * Returns a descriptive object for each key whose values are deeply unequal
106 * between two provided objects. Useful for debugging shouldComponentUpdate.
107 */
108export function getDeepUnequalKeyValues(objA, objB, keys) {
109 if (objA === void 0) { objA = {}; }
110 if (objB === void 0) { objB = {}; }
111 var filteredKeys = keys == null ? unionKeys(objA, objB) : keys;
112 return getUnequalKeyValues(objA, objB, filteredKeys, function (a, b, key) {
113 return deepCompareKeys(a, b, [key]);
114 });
115}
116// Private helpers
117// ===============
118/**
119 * Partial shallow comparison between objects using the given list of keys.
120 */
121function shallowCompareKeysImpl(objA, objB, keys) {
122 return filterKeys(objA, objB, keys).every(function (key) {
123 return objA.hasOwnProperty(key) === objB.hasOwnProperty(key) && objA[key] === objB[key];
124 });
125}
126/**
127 * Partial deep comparison between objects using the given list of keys.
128 */
129function deepCompareKeysImpl(objA, objB, keys) {
130 return keys.every(function (key) {
131 return objA.hasOwnProperty(key) === objB.hasOwnProperty(key) && deepCompareKeys(objA[key], objB[key]);
132 });
133}
134function isSimplePrimitiveType(value) {
135 return typeof value === "number" || typeof value === "string" || typeof value === "boolean";
136}
137function filterKeys(objA, objB, keys) {
138 if (isAllowlist(keys)) {
139 return keys.include;
140 }
141 else if (isDenylist(keys)) {
142 var keysA = Object.keys(objA);
143 var keysB = Object.keys(objB);
144 // merge keys from both objects into a big set for quick access
145 var keySet_1 = arrayToObject(keysA.concat(keysB));
146 // delete denied keys from the key set
147 keys.exclude.forEach(function (key) { return delete keySet_1[key]; });
148 // return the remaining keys as an array
149 return Object.keys(keySet_1);
150 }
151 return [];
152}
153function isAllowlist(keys) {
154 return keys != null && keys.include != null;
155}
156function isDenylist(keys) {
157 return keys != null && keys.exclude != null;
158}
159function arrayToObject(arr) {
160 return arr.reduce(function (obj, element) {
161 obj[element] = true;
162 return obj;
163 }, {});
164}
165function getUnequalKeyValues(objA, objB, keys, compareFn) {
166 var unequalKeys = keys.filter(function (key) { return !compareFn(objA, objB, key); });
167 var unequalKeyValues = unequalKeys.map(function (key) { return ({
168 key: key,
169 valueA: objA[key],
170 valueB: objB[key],
171 }); });
172 return unequalKeyValues;
173}
174function unionKeys(objA, objB) {
175 var keysA = Object.keys(objA);
176 var keysB = Object.keys(objB);
177 var concatKeys = keysA.concat(keysB);
178 var keySet = arrayToObject(concatKeys);
179 return Object.keys(keySet);
180}
181//# sourceMappingURL=compareUtils.js.map
\No newline at end of file