Skip to main content
Module

x/ramda/internal/_equals.js

:ram: Practical functional Javascript
Very Popular
Go to Latest
File
import _arrayFromIterator from './_arrayFromIterator';import _includesWith from './_includesWith';import _functionName from './_functionName';import _has from './_has';import _objectIs from './_objectIs';import keys from '../keys';import type from '../type';
/** * private _uniqContentEquals function. * That function is checking equality of 2 iterator contents with 2 assumptions * - iterators lengths are the same * - iterators values are unique * * false-positive result will be returned for comparision of, e.g. * - [1,2,3] and [1,2,3,4] * - [1,1,1] and [1,2,3] * */
function _uniqContentEquals(aIterator, bIterator, stackA, stackB) { var a = _arrayFromIterator(aIterator); var b = _arrayFromIterator(bIterator);
function eq(_a, _b) { return _equals(_a, _b, stackA.slice(), stackB.slice()); }
// if *a* array contains any element that is not included in *b* return !_includesWith(function(b, aItem) { return !_includesWith(eq, aItem, b); }, b, a);}
export default function _equals(a, b, stackA, stackB) { if (_objectIs(a, b)) { return true; }
var typeA = type(a);
if (typeA !== type(b)) { return false; }
if (a == null || b == null) { return false; }
if (typeof a['fantasy-land/equals'] === 'function' || typeof b['fantasy-land/equals'] === 'function') { return typeof a['fantasy-land/equals'] === 'function' && a['fantasy-land/equals'](b) && typeof b['fantasy-land/equals'] === 'function' && b['fantasy-land/equals'](a); }
if (typeof a.equals === 'function' || typeof b.equals === 'function') { return typeof a.equals === 'function' && a.equals(b) && typeof b.equals === 'function' && b.equals(a); }
switch (typeA) { case 'Arguments': case 'Array': case 'Object': if (typeof a.constructor === 'function' && _functionName(a.constructor) === 'Promise') { return a === b; } break; case 'Boolean': case 'Number': case 'String': if (!(typeof a === typeof b && _objectIs(a.valueOf(), b.valueOf()))) { return false; } break; case 'Date': if (!_objectIs(a.valueOf(), b.valueOf())) { return false; } break; case 'Error': return a.name === b.name && a.message === b.message; case 'RegExp': if (!(a.source === b.source && a.global === b.global && a.ignoreCase === b.ignoreCase && a.multiline === b.multiline && a.sticky === b.sticky && a.unicode === b.unicode)) { return false; } break; }
var idx = stackA.length - 1; while (idx >= 0) { if (stackA[idx] === a) { return stackB[idx] === b; } idx -= 1; }
switch (typeA) { case 'Map': if (a.size !== b.size) { return false; }
return _uniqContentEquals(a.entries(), b.entries(), stackA.concat([a]), stackB.concat([b])); case 'Set': if (a.size !== b.size) { return false; }
return _uniqContentEquals(a.values(), b.values(), stackA.concat([a]), stackB.concat([b])); case 'Arguments': case 'Array': case 'Object': case 'Boolean': case 'Number': case 'String': case 'Date': case 'Error': case 'RegExp': case 'Int8Array': case 'Uint8Array': case 'Uint8ClampedArray': case 'Int16Array': case 'Uint16Array': case 'Int32Array': case 'Uint32Array': case 'Float32Array': case 'Float64Array': case 'ArrayBuffer': break; default: // Values of other types are only equal if identical. return false; }
var keysA = keys(a); if (keysA.length !== keys(b).length) { return false; }
var extendedStackA = stackA.concat([a]); var extendedStackB = stackB.concat([b]);
idx = keysA.length - 1; while (idx >= 0) { var key = keysA[idx]; if (!(_has(key, b) && _equals(b[key], a[key], extendedStackA, extendedStackB))) { return false; } idx -= 1; } return true;}