Skip to content

Instantly share code, notes, and snippets.

@stefanmaric
Last active September 2, 2016 03:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stefanmaric/eabd15012b2e0020aabf to your computer and use it in GitHub Desktop.
Save stefanmaric/eabd15012b2e0020aabf to your computer and use it in GitHub Desktop.
Deep (recursive) diff function implementation in Angular, lodash and ES6 / ES2015.
function deepDiffRight (left, right) {
// if they are equals, return undefined
if (angular.equals(left, right)) return
// form now on, we can assure that `left` and `right` are not equals (equivalents)
// if `left` and `right` are primitives, value changed
// if `left` is a primitive and `right` an object, value has been replaced with an object
// if `left` is an object and `right` a primitive, value has been replaced with a primitive
// use `_.copy` to prevent object referrence issues
if (!angular.isObject(left) || !angular.isObject(right)) return angular.copy(right)
// make `result` the same type as `right`
var result = angular.isArray(right) ? [] : {}
// since we know that both are objects,
// iterate on `right` to see what changed or what's new in `right`
angular.forEach(right, function (value, key) {
// recursion
var diff = deepDiffRight(left[key], right[key])
// since the function returns undefined when `left` and `right` are equals,
// only assing non-undefined values to result
if (!angular.isUndefined(diff)) result[key] = diff
});
return result
}
_.mixin({ 'deepDiffRight': function deepDiffRight (left, right) {
// if they are equals, return undefined
if (_.isEqual(left, right)) return
// form now on, we can assure that `left` and `right` are not equals (equivalents)
// if `left` and `right` are primitives, value changed
// if `left` is a primitive and `right` an object, value has been replaced with an object
// if `left` is an object and `right` a primitive, value has been replaced with a primitive
// use `_.cloneDeep` to prevent object referrence issues
if (!_.isObject(left) || !_.isObject(right)) return _.cloneDeep(right)
// since we know that both are objects,
// iterate on `right` to see what changed or what's new in `right`
return _.transform(right, function (result, n, key) {
// recursion
var diff = deepDiffRight(left[key], right[key])
// since the function returns undefined when `left` and `right` are equals,
// only assing non-undefined values to result
if (diff !== undefined) result[key] = diff
})
}})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment