diff --git a/snippets/equals.md b/snippets/equals.md new file mode 100644 index 000000000..75be4aba9 --- /dev/null +++ b/snippets/equals.md @@ -0,0 +1,27 @@ +### equals + +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 (non-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])); +}; +``` + +```js +equals({ a: [2, {e: 3}], b: [4], c: 'foo' }, { a: [2, {e: 3}], b: [4], c: 'foo' }); // true +``` diff --git a/tag_database b/tag_database index 257a66fb3..b7d1682f6 100644 --- a/tag_database +++ b/tag_database @@ -38,6 +38,7 @@ dropElements:array,function dropRight:array elementIsVisibleInViewport:browser elo:math,array,advanced +equals:object,array,type,advanced escapeHTML:string,browser,regexp escapeRegExp:string,regexp everyNth:array diff --git a/test/equals/equals.js b/test/equals/equals.js new file mode 100644 index 000000000..bb2518921 --- /dev/null +++ b/test/equals/equals.js @@ -0,0 +1,13 @@ +module.exports = 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])); +}; \ No newline at end of file diff --git a/test/equals/equals.test.js b/test/equals/equals.test.js new file mode 100644 index 000000000..eaa62a6ba --- /dev/null +++ b/test/equals/equals.test.js @@ -0,0 +1,18 @@ +const test = require('tape'); +const equals = require('./equals.js'); + +test('Testing equals', (t) => { + //For more information on all the methods supported by tape + //Please go to https://github.com/substack/tape + t.true(typeof equals === 'function', 'equals is a Function'); + t.true(equals({ a: [2, {e: 3}], b: [4], c: 'foo' }, { a: [2, {e: 3}], b: [4], c: 'foo' }), "{ a: [2, {e: 3}], b: [4], c: 'foo' } is equal to { a: [2, {e: 3}], b: [4], c: 'foo' }"); + t.true(equals([1, 2, 3], [1, 2, 3]), '[1,2,3] is equal to [1,2,3]'); + t.false(equals({ a: [2, 3], b: [4] }, { a: [2, 3], b: [6] }), '{ a: [2, 3], b: [4] } is not equal to { a: [2, 3], b: [6] }'); + t.false(equals([1, 2, 3], [1, 2, 4]), '[1,2,3] is not equal to [1,2,4]'); + t.true(equals([1, 2, 3], { 0: 1, 1: 2, 2: 3 }), '[1, 2, 3] should be equal to { 0: 1, 1: 2, 2: 3 }) - type is different, but their enumerable properties match.') + //t.deepEqual(equals(args..), 'Expected'); + //t.equal(equals(args..), 'Expected'); + //t.false(equals(args..), 'Expected'); + //t.throws(equals(args..), 'Expected'); + t.end(); +});