I've been tasked with finding property differences in massive JSON structures and return them in a particular fashion ([key_1.key_2, key_1, etc]).
Here's my code, which is focused on readability so some redundant decorators are used (they will be removed). I am looking for any performance/logical problems with this approach.
It also has to be in JavaScript, Node Stack (Isomorphic).
/**
* --Decorator for prettiness--
* Checks array if key exists
* @param needle
* @param haystack
* @returns {boolean}
*/
export function inArray (needle, haystack) {
return haystack.indexOf(needle) > -1
}
/**
* --Decorator for prettiness--
* Merge two arrays together
* @param array_1 {Array}
* @param array_2 {Array}
* @returns {Array}
*/
export function arrayMerge(array_1, array_2) {
return array_1.concat(array_2)
}
/**
* Returns all differences of keys
* Note: nested keys are returned like this [key_1.key_2, key_1.key_2.key_3]
* @param object_compare
* @param object_against
* @param ignoreKeys
* @param depth
* @returns {Array}
*/
export function diffKeysRecursive(object_compare, object_against, ignoreKeys = [], depth = '') {
function _isObject(mixed) {
return typeof mixed === 'object'
}
function _propExists(prop, object) {
return typeof object === 'object' && typeof object[prop] !== 'undefined'
}
function _depthPath(prop, depth = '') {
return depth = depth ? `${depth}.${prop}` : prop
}
if (_isObject(object_against)) {
var diffs = []
// Iterate through the against object to see differences in the compare
$.each(object_against, (prop, value_against) => {
// Checks if prop should be ignored
if(!inArray(prop, ignoreKeys)) {
if (!_propExists(prop, object_compare)) {
diffs.push(_depthPath(prop, depth))
}
// Recurse if value_against is an object
if (_isObject(value_against)) {
var object_compare_safe = _propExists(prop, object_compare) ? object_compare[prop] : null
diffs = arrayMerge(diffs, diffKeysRecursive(object_compare_safe, value_against, _depthPath(prop, depth)))
}
}
})
return diffs
} else {
throw 'Invalid Type Supplied'
}
}