Skip to content

Instantly share code, notes, and snippets.

@acrylic-style
Last active November 27, 2021 04:01
Show Gist options
  • Save acrylic-style/0a8c4003d1c61cc3aff43e023f939452 to your computer and use it in GitHub Desktop.
Save acrylic-style/0a8c4003d1c61cc3aff43e023f939452 to your computer and use it in GitHub Desktop.
Merge data1.json and data2.json, and you get result.json
const fs = require('fs/promises')
const util = require('util')
const process = (k1, v1, k2, v2) => {
if (util.isDeepStrictEqual(v1, v2)) return v1
if (typeof v1 === 'undefined' || v1 === null) return v2
if (typeof v2 === 'undefined' || v2 === null) return v1
let data = null
if (Array.isArray(v1) !== Array.isArray(v2)) {
if (Array.isArray(v1)) {
throw new Error(`${k1} is array, but ${k2} is not an array`)
} else {
throw new Error(`${k2} is array, but ${k1} is not an array`)
}
}
if ((typeof v1 === 'object') !== (typeof v2 === 'object')) {
if (typeof v1 === 'object') {
throw new Error(`${k1} is object, but ${k2} is not an object`)
} else {
throw new Error(`${k2} is object, but ${k1} is not an object`)
}
}
if (Array.isArray(v1)) {
data = v1
data.push(...v2)
} else if (typeof v1 === 'object') {
data = {}
const keys = Object.keys(v1)
keys.push(...Object.keys(v2))
for (const key of keys.filter((v, i, a) => a.indexOf(v) === i)) {
data[key] = process(`${k1}.${key}`, v1[key], `${k2}.${key}`, v2[key])
}
} else {
if (v1 !== v2) {
throw new Error(`Conflict: ${k1} = ${JSON.stringify(v1)} and ${k2} = ${JSON.stringify(v2)}`)
}
}
return data
}
!(async () => {
const data1 = JSON.parse((await fs.readFile('data1.json')).toString('utf8'))
const data2 = JSON.parse((await fs.readFile('data2.json')).toString('utf8'))
const data = process('data1', data1, 'data2', data2)
await fs.writeFile('result.json', JSON.stringify(data), { encoding: 'utf8' })
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment