UNPKG

2.28 kBJavaScriptView Raw
1var collectionCompare = compare;
2
3/*
4 primitives: value1 === value2
5 functions: value1.toString == value2.toString
6 arrays: if length, sequence and values of properties are identical
7 objects: if length, names and values of properties are identical
8 compare([[1, [2, 3]], [[1, [2, 3]]); // true
9 compare([[1, [2, 3], 4], [[1, [2, 3]]); // false
10 compare({a: 2, b: 3}, {a: 2, b: 3}); // true
11 compare({a: 2, b: 3}, {b: 3, a: 2}); // true
12 compare({a: 2, b: 3, c: 4}, {a: 2, b: 3}); // false
13 compare({a: 2, b: 3}, {a: 2, b: 3, c: 4}); // false
14 compare([[1, [2, {a: 4}], 4], [[1, [2, {a: 4}]]); // true
15*/
16
17function compare(value1, value2) {
18 if (value1 === value2) {
19 return true;
20 }
21 /* eslint-disable no-self-compare */
22 // if both values are NaNs return true
23 if (value1 !== value1 && value2 !== value2) {
24 return true;
25 }
26 if ({}.toString.call(value1) != {}.toString.call(value2)) {
27 return false;
28 }
29 if (value1 !== Object(value1)) {
30 // non equal primitives
31 return false;
32 }
33 if (!value1) {
34 return false;
35 }
36 if (Array.isArray(value1)) {
37 return compareArrays(value1, value2);
38 }
39 if ({}.toString.call(value1) == '[object Set]') {
40 return compareArrays(Array.from(value1), Array.from(value2));
41 }
42 if ({}.toString.call(value1) == '[object Object]') {
43 return compareObjects(value1, value2);
44 } else {
45 return compareNativeSubtypes(value1, value2);
46 }
47}
48
49function compareNativeSubtypes(value1, value2) {
50 // e.g. Function, RegExp, Date
51 return value1.toString() === value2.toString();
52}
53
54function compareArrays(value1, value2) {
55 var len = value1.length;
56 if (len != value2.length) {
57 return false;
58 }
59 var alike = true;
60 for (var i = 0; i < len; i++) {
61 if (!compare(value1[i], value2[i])) {
62 alike = false;
63 break;
64 }
65 }
66 return alike;
67}
68
69function compareObjects(value1, value2) {
70 var keys1 = Object.keys(value1).sort();
71 var keys2 = Object.keys(value2).sort();
72 var len = keys1.length;
73 if (len != keys2.length) {
74 return false;
75 }
76 for (var i = 0; i < len; i++) {
77 var key1 = keys1[i];
78 var key2 = keys2[i];
79 if (!(key1 == key2 && compare(value1[key1], value2[key2]))) {
80 return false;
81 }
82 }
83 return true;
84}
85
86export {collectionCompare as default};