Created
August 16, 2018 01:00
-
-
Save tusharmath/64ddd63174541f6a4fb208aa177626a7 to your computer and use it in GitHub Desktop.
Finds diff between 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
type Change<T> = { | |
path: Array<string> | |
right: T | |
left: T | |
} | |
function isPrimitive(value: any): boolean { | |
const type = typeof value | |
return ['number', 'date', 'boolean', 'string'].indexOf(type) > -1 | |
} | |
function change<T>(path: Array<string>, a: T, b: T): Change<T> { | |
return { | |
path, | |
left: a, | |
right: b | |
} | |
} | |
function arrToDict<T>(t: Array<T>): { [key: number]: T } { | |
const obj: any = {} | |
for (let i = 0; i < t.length; i++) obj[i] = t[i] | |
return obj | |
} | |
function diffAB<T extends any>(a: T, b: T, path: string[]): Array<Change<T>> { | |
let changes: Array<Change<any>> = [] | |
for (let i in a) { | |
if (a.hasOwnProperty(i)) { | |
if (b.hasOwnProperty(i)) { | |
changes = changes.concat(diff(a[i], b[i], [...path, i])) | |
} else { | |
changes = changes.concat([change([...path, i], a[i], b[i])]) | |
} | |
} | |
} | |
for (let i in b) { | |
if (b.hasOwnProperty(i)) { | |
if (!a.hasOwnProperty(i)) { | |
changes = changes.concat([change([...path, i], a[i], b[i])]) | |
} | |
} | |
} | |
return changes | |
} | |
function diff(a: any, b: any, path: Array<string> = []): Array<Change<any>> { | |
if (a === b) return [] | |
// primitive check | |
if ( | |
(isPrimitive(a) && !isPrimitive(b)) || | |
(!isPrimitive(a) && isPrimitive(b)) || | |
(isPrimitive(a) && isPrimitive(b) && a !== b) | |
) | |
return [change(path, a, b)] | |
if (Array.isArray(a) && Array.isArray(b)) | |
return diffAB(arrToDict(a), arrToDict(b), path) | |
return diffAB(a, b, path) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment