dev-sidecar/packages/core/src/merge.js

88 lines
2.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

const lodash = require('lodash')
/**
* 找出 newObj 相对于 oldObj 有差异的部分
*
* @param oldObj
* @param newObj
* @returns {{}|*}
*/
function doDiff (oldObj, newObj) {
if (newObj == null) {
return oldObj
}
// 临时的对象,用于找出被删除的数据
const tempObj = { ...oldObj }
// 删除空项,使差异对象更干净一些,体现出用户自定义内容
deleteNullItems(tempObj)
// 保存差异的对象
const diffObj = {}
// 读取新对象,并解析
for (const key in newObj) {
const newValue = newObj[key]
const oldValue = oldObj[key]
// 新值不为空,旧值为空时,直接取新值
if (newValue != null && oldValue == null) {
diffObj[key] = newValue
continue
}
// 新旧值相等时,忽略
if (lodash.isEqual(newValue, oldValue)) {
delete tempObj[key]
continue
}
// 新的值为数组时,直接取新值
if (lodash.isArray(newValue)) {
diffObj[key] = newValue
delete tempObj[key]
continue
}
// 新的值为对象时,递归合并
if (lodash.isObject(newValue)) {
diffObj[key] = doDiff(oldValue, newValue)
delete tempObj[key]
continue
}
// 基础类型,直接覆盖
delete tempObj[key]
diffObj[key] = newValue
}
// tempObj 里面剩下的是被删掉的数据
lodash.forEach(tempObj, (oldValue, key) => {
// 将被删除的属性设置为null目的是为了merge时将被删掉的对象设置为null达到删除的目的
diffObj[key] = null
})
return diffObj
}
function deleteNullItems (target) {
lodash.forEach(target, (item, key) => {
if (item == null) {
delete target[key]
}
if (lodash.isObject(item)) {
deleteNullItems(item)
}
})
}
module.exports = {
doMerge: function (oldObj, newObj) {
return lodash.mergeWith(oldObj, newObj, function (objValue, srcValue) {
if (lodash.isArray(objValue)) {
return srcValue
}
})
},
doDiff,
deleteNullItems
}