A small library that can deep diff two JavaScript Objects, including nested structures of arrays and objects.
yarn add deep-object-diff
npm i --save deep-object-diff
-
diff(originalObj, updatedObj)returns the difference of the original and updated objects -
addedDiff(original, updatedObj)returns only the values added to the updated object -
deletedDiff(original, updatedObj)returns only the values deleted in the updated object -
updatedDiff(original, updatedObj)returns only the values that have been changed in the updated object -
detailedDiff(original, updatedObj)returns an object with the added, deleted and updated differences -
changelogedDiff(original, updatedObj)returns an object with the added, deleted and updated differences in changelog format
import { diff, addedDiff, deletedDiff, updatedDiff, detailedDiff, changelogedDiff } from 'deep-object-diff';const lhs = { foo: { bar: { a: ['a', 'b'], b: 2, c: ['x', 'y'], e: 100 // deleted } }, buzz: 'world' }; const rhs = { foo: { bar: { a: ['a'], // index 1 ('b') deleted b: 2, // unchanged c: ['x', 'y', 'z'], // 'z' added d: 'Hello, world!' // added } }, buzz: 'fizz' // updated }; console.log(diff(lhs, rhs)); // => /* { foo: { bar: { a: { '1': undefined }, c: { '2': 'z' }, d: 'Hello, world!', e: undefined } }, buzz: 'fizz' } */const lhs = { foo: { bar: { a: ['a', 'b'], b: 2, c: ['x', 'y'], e: 100 // deleted } }, buzz: 'world' }; const rhs = { foo: { bar: { a: ['a'], // index 1 ('b') deleted b: 2, // unchanged c: ['x', 'y', 'z'], // 'z' added d: 'Hello, world!' // added } }, buzz: 'fizz' // updated }; console.log(addedDiff(lhs, rhs)); /* { foo: { bar: { c: { '2': 'z' }, d: 'Hello, world!' } } } */const lhs = { foo: { bar: { a: ['a', 'b'], b: 2, c: ['x', 'y'], e: 100 // deleted } }, buzz: 'world' }; const rhs = { foo: { bar: { a: ['a'], // index 1 ('b') deleted b: 2, // unchanged c: ['x', 'y', 'z'], // 'z' added d: 'Hello, world!' // added } }, buzz: 'fizz' // updated }; console.log(deletedDiff(lhs, rhs)); /* { foo: { bar: { a: { '1': undefined }, e: undefined } } } */const lhs = { foo: { bar: { a: ['a', 'b'], b: 2, c: ['x', 'y'], e: 100 // deleted } }, buzz: 'world' }; const rhs = { foo: { bar: { a: ['a'], // index 1 ('b') deleted b: 2, // unchanged c: ['x', 'y', 'z'], // 'z' added d: 'Hello, world!' // added } }, buzz: 'fizz' // updated }; console.log(updatedDiff(lhs, rhs)); /* { buzz: 'fizz' } */const lhs = { foo: { bar: { a: ['a', 'b'], b: 2, c: ['x', 'y'], e: 100 // deleted } }, buzz: 'world' }; const rhs = { foo: { bar: { a: ['a'], // index 1 ('b') deleted b: 2, // unchanged c: ['x', 'y', 'z'], // 'z' added d: 'Hello, world!' // added } }, buzz: 'fizz' // updated }; console.log(detailedDiff(lhs, rhs)); /* { added: { foo: { bar: { c: { '2': 'z' }, d: 'Hello, world!' } } }, deleted: { foo: { bar: { a: { '1': undefined }, e: undefined } } }, updated: { buzz: 'fizz' } } */antoher output format: changelog
structure from: github.com/r3labs/diff
type Change struct { Type string // The type of change detected; can be one of create, update or delete Path []string // The path of the detected change; will contain any field name or array index that was part of the traversal From interface{} // The original value that was present in the "from" structure To interface{} // The new value that was detected as a change in the "to" structure } type Changelog = []Changeconst lhs = { a: { b: [[1, 2, 3, 4]] }, c: [], e: 'e' }; const rhs = { a: { b: [[1, 2, 9999, 4]] }, c: 10, d: 'd' }; console.log(changelogDiff(lhs, rhs)); /* [ { type: 'create', path: ['d'], from: undefined, to: 'd' }, { type: 'delete', path: ['e'], from: 'e', to: undefined }, { type: 'update', path: ['a', 'b', '0', '2'], from: 3, to: 9999 }, { type: 'update', path: ['c'], from: [], to: 10 }, ] */MIT