diff --git a/README.md b/README.md index 84bc8a762..5eee0eacb 100644 --- a/README.md +++ b/README.md @@ -267,6 +267,7 @@ average(1, 2, 3); View contents * [`cleanObj`](#cleanobj) +* [`equals`](#equals-) * [`functions`](#functions) * [`invertKeyValues`](#invertkeyvalues) * [`lowercaseKeys`](#lowercasekeys) @@ -3998,6 +3999,39 @@ cleanObj(testObj, ['a'], 'children'); // { a: 1, children : { a: 1}}
[⬆ Back to top](#table-of-contents) +### equals ![advanced](/advanced.svg) + +Performs a deep comparison between two values to determine if they are equivalent. + +Check if the two values are identical, if they are both `Date` objects with the same time, using `Date.getTime()` or if they are both non-object values with an equivalent value (strict comparison). +Check if only one value is `null` or `undefined` or if their prototypes differ. +If none of the above conditions are met, use `Object.keys()` to check if both values have the same number of keys, then use `Array.every()` to check if every key in the first value exists in the second one and if they are equivalent by calling this method recursively. + +```js +const equals = (a, b) => { + if (a === b) return true; + if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime(); + if (!a || !b || (typeof a != 'object' && typeof b !== 'object')) return a === b; + if (a === null || a === undefined || b === null || b === undefined) return false; + if (a.prototype !== b.prototype) return false; + let keys = Object.keys(a); + if (keys.length !== Object.keys(b).length) return false; + return keys.every(k => equals(a[k], b[k])); +}; +``` + +
+Examples + +```js +equals({ a: [2, { e: 3 }], b: [4], c: 'foo' }, { a: [2, { e: 3 }], b: [4], c: 'foo' }); // true +``` + +
+ +
[⬆ Back to top](#table-of-contents) + + ### functions Returns an array of function property names from own (and optionally inherited) enumerable properties of an object. diff --git a/docs/index.html b/docs/index.html index 4b9013c18..ca951fb05 100644 --- a/docs/index.html +++ b/docs/index.html @@ -50,7 +50,7 @@ scrollToTop(); } }, false); - }

logo 30 seconds of code Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.

 

Adapter

call

Given a key and a set of arguments, call them when given a context. Primarily useful in composition.

Use a closure to call a stored key with stored arguments.

const call = (key, ...args) => context => context[key](...args);
+      }

logo 30 seconds of code Curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.

 

Adapter

call

Given a key and a set of arguments, call them when given a context. Primarily useful in composition.

Use a closure to call a stored key with stored arguments.

const call = (key, ...args) => context => context[key](...args);
 
Promise.resolve([1, 2, 3])
   .then(call('map', x => 2 * x))
   .then(console.log); //[ 2, 4, 6 ]
@@ -873,6 +873,17 @@ console.log<
 };
 
const testObj = { a: 1, b: 2, children: { a: 1, b: 2 } };
 cleanObj(testObj, ['a'], 'children'); // { a: 1, children : { a: 1}}
+

equalsadvanced

Performs a deep comparison between two values to determine if they are equivalent.

Check if the two values are identical, if they are both Date objects with the same time, using Date.getTime() or if they are both non-object values with an equivalent value (strict comparison). Check if only one value is null or undefined or if their prototypes differ. If none of the above conditions are met, use Object.keys() to check if both values have the same number of keys, then use Array.every() to check if every key in the first value exists in the second one and if they are equivalent by calling this method recursively.

const equals = (a, b) => {
+  if (a === b) return true;
+  if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime();
+  if (!a || !b || (typeof a != 'object' && typeof b !== 'object')) return a === b;
+  if (a === null || a === undefined || b === null || b === undefined) return false;
+  if (a.prototype !== b.prototype) return false;
+  let keys = Object.keys(a);
+  if (keys.length !== Object.keys(b).length) return false;
+  return keys.every(k => equals(a[k], b[k]));
+};
+
equals({ a: [2, { e: 3 }], b: [4], c: 'foo' }, { a: [2, { e: 3 }], b: [4], c: 'foo' }); // true
 

functions

Returns an array of function property names from own (and optionally inherited) enumerable properties of an object.

Use Object.keys(obj) to iterate over the object's own properties. If inherited is true, use Object.get.PrototypeOf(obj) to also get the object's inherited properties. Use Array.filter() to keep only those properties that are functions. Omit the second argument, inherited, to not include inherited properties by default.

const functions = (obj, inherited = false) =>
   (inherited
     ? [...Object.keys(obj), ...Object.keys(Object.getPrototypeOf(obj))]
diff --git a/snippets/equals.md b/snippets/equals.md
index 535531bf9..e62c52120 100644
--- a/snippets/equals.md
+++ b/snippets/equals.md
@@ -9,12 +9,9 @@ If none of the above conditions are met, use `Object.keys()` to check if both va
 ```js
 const equals = (a, b) => {
   if (a === b) return true;
-  if (a instanceof Date && b instanceof Date)
-    return a.getTime() === b.getTime();
-  if (!a || !b || (typeof a != 'object' && typeof b !== 'object'))
-    return a === b;
-  if (a === null || a === undefined || b === null || b === undefined)
-    return false;
+  if (a instanceof Date && b instanceof Date) return a.getTime() === b.getTime();
+  if (!a || !b || (typeof a != 'object' && typeof b !== 'object')) return a === b;
+  if (a === null || a === undefined || b === null || b === undefined) return false;
   if (a.prototype !== b.prototype) return false;
   let keys = Object.keys(a);
   if (keys.length !== Object.keys(b).length) return false;
@@ -23,5 +20,5 @@ const equals = (a, b) => {
 ```
 
 ```js
-equals({ a: [2, {e: 3}], b: [4], c: 'foo' }, { a: [2, {e: 3}], b: [4], c: 'foo' }); // true
+equals({ a: [2, { e: 3 }], b: [4], c: 'foo' }, { a: [2, { e: 3 }], b: [4], c: 'foo' }); // true
 ```