Skip to content

Instantly share code, notes, and snippets.

@trevorhreed
Created October 19, 2022 04:13
Show Gist options
  • Save trevorhreed/89d664dfd9601458e23eae8b82b5cd01 to your computer and use it in GitHub Desktop.
Save trevorhreed/89d664dfd9601458e23eae8b82b5cd01 to your computer and use it in GitHub Desktop.
Get a diff of two json objects
const diff = (a, b, path = '') => {
let diffs = []
const {
type: typeA,
value: valueA
} = diff.meta(a)
const {
type: typeB,
value: valueB
} = diff.meta(b)
if (typeA !== typeB) {
diffs.push(`${path}: t{${typeA}, ${typeB}}`)
} else if (typeA === 'array') {
const length = Math.max(a.length, b.length)
for (let i = 0; i < length; i++) {
const subpath = path ? `${path}.${i}` : `${i}`
const subDiffs = diff(a[i], b[i], subpath)
diffs = diffs.concat(subDiffs)
}
} else if (typeA === 'object') {
const keys = [...new Set([...Object.keys(a), ...Object.keys(b)])]
for (const key of keys) {
const subpath = path ? `${path}.${key}` : `${key}`
const subDiffs = diff(a[key], b[key], subpath)
diffs = diffs.concat(subDiffs)
}
} else if (a !== b) {
diffs.push(`${path}: v{${valueA}, ${valueB}}`)
}
return diffs
}
diff.meta = o => {
const type = diff.type(o)
switch (type) {
case 'date':
return {
type, value: o.toLocaleString()
}
case 'regex':
return {
type, value: JSON.stringify(o)
}
case 'error':
return {
type, value: o.message
}
case 'function':
return {
type, value: o.toString()
}
default:
return {
type, value: '' + o
}
}
}
diff.basicTypes = [
'string',
'number',
'boolean',
'function',
'undefined',
'null'
]
diff.type = o => {
const type = typeof o
if (diff.basicTypes.includes(type)) return type
if (Array.isArray(o)) return 'array'
if (o instanceof Date) return 'date'
if (o instanceof RegExp) return 'regex'
if (o instanceof Error) return 'error'
if (o && typeof o.constructor === 'function') {
if (o.constructor.name === 'Object') return 'object'
return o.constructor.name
}
return `unknown ${type}`
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment