Created
June 7, 2014 12:08
-
-
Save aercolino/e72bd4f4754a74deb969 to your computer and use it in GitHub Desktop.
A jQuery plugin for equality comparisons of JavaScript scalars and objects.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$.equals = function( a, b, options ) { | |
options = $.extend({ | |
// if true, in case of inequality, a trace of the first difference is logged to the console | |
verbose: false, | |
// use 'strict' for ===, 'abstract' for == | |
comparison: 'strict', | |
// if true, an item is compared, otherwise it is ignored | |
// receives a value and a key, returns true or false | |
filter: function () { | |
return true; | |
} | |
}, options || {}); | |
var outmost = false; | |
if (typeof options.trace == 'undefined') { | |
outmost = true; | |
options.trace = []; | |
} | |
if (options.comparison == 'strict' ? a === b : a == b) { | |
return true; | |
} | |
var ta = $.type(a); | |
var tb = $.type(b); | |
if (! (ta == tb)) { | |
log(['types', ta, tb, a, b]); | |
return false; | |
} | |
var aa = decompose(a, options.filter); | |
var bb = decompose(b, options.filter); | |
var la = aa.keys.length; | |
var lb = bb.keys.length; | |
if (! (la == lb)) { | |
log(['lengths', la, lb, a, b]); | |
return false; | |
} | |
var length = la; // == lb | |
if (length == 0) { // a and b are scalar | |
return a === b; | |
} | |
// compare corresponding elements | |
for (var i = 0; i < length; i++) { | |
var key = aa.keys[i]; | |
var a_value = a[key]; | |
var b_value = b[key]; | |
var equal = $.equals( a_value, b_value, options ); | |
if (! equal) { | |
log(['values at key "' + key + '"', a_value, b_value, a, b]); | |
return false; | |
} | |
} | |
if (outmost) { | |
log(['values', null, null, a, b]); | |
} | |
return true; | |
//--- | |
// returns true if the given object is a scalar (not in JavaScript terms, though...) | |
function isScalar(object) { | |
return object === null || /undefined|boolean|number|string/.test(typeof object); | |
} | |
// returns a plain object with the given object's items correspondingly split into keys and values arrays | |
function decompose(object, filter) { | |
if (isScalar(object)) { | |
return { | |
keys: [], | |
values: filter(object) ? object : null | |
}; | |
} | |
var keys = []; | |
var values = []; | |
for (var key in object) { | |
var value = object[key]; | |
if (filter(value, key)) { | |
keys.push(key); | |
values.push(value); | |
} | |
} | |
return {keys: keys, values: values}; | |
} | |
// returns a plain object with the given decomposed's keys and values arrays correspondingly joined into items | |
// note that | |
// (1) compose(decompose(plain_object)) == plain_object | |
// (2) compose(decompose(non_plain_object)) != non_plain_object | |
function compose(decomposed) { | |
var result = {}; | |
for (var i = 0, iTop = decomposed.keys.length; i < iTop; i++) { | |
result[decomposed.keys[i]] = decomposed.values[i]; | |
} | |
return result; | |
} | |
// logs given data to the console if it's the outmost log, otherwise it only remembers | |
function log(data) { | |
if (! options.verbose) return; | |
options.trace.push(data); | |
if (outmost) { | |
console_log(''); | |
while (options.trace.length) { | |
console_log(' '); | |
} | |
} | |
//--- | |
function console_log(prefix) { | |
var top = options.trace.pop(); | |
var data = compose({keys: ['difference', 'a_value', 'b_value', 'a', 'b'], values: top}); | |
if ('values' == data.difference) { | |
console.log(' ($.equals)', prefix + 'comparing(', data.a, ', ', data.b, ')\n', | |
'($.equals)', prefix + ' found different values'); | |
} | |
else { | |
console.log(' ($.equals)', prefix + 'comparing(', data.a, ', ', data.b, ')\n', | |
'($.equals)', prefix + ' found different', data.difference, data.a_value, '!=', data.b_value); | |
} | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See http://andowebsit.es/blog/noteslog.com/post/how-to-know-whether-two-values-are-equal-or-not/