我想合并两个相似但不相同的对象,并在其中一个中覆盖空值(如果存在)。例如,我将拥有以下两个对象:
const obj1 = {
a: 1,
b: '',
c: [],
d: null
}
const obj2 = {
a: 2,
b: null,
d: 1
}
合并的效果应该是:
const objMerged = {
a: 2,
b: '',
c: [],
d: 1
}
换句话说,合并对象中最重要的数据源是obj2
,但是它缺少obj1
的某些属性,因此需要复制它们,还有一些{{1} }值为obj2
,因此也应从null
中获取。
编辑 我尝试过:
obj1
和
_.extend({}, obj1, obj2)
答案 0 :(得分:2)
您还可以与ES6 destructuring和lodash _.omitBy
混合搭配:
const obj1 = { a: 1, b: '', c: [], d: null }
const obj2 = { a: 2, b: null, d: 1 }
const result = {..._.omitBy(obj1, _.isNull), ..._.omitBy(obj2, _.isNull)}
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
您也可以只使用ES6来做到这一点:
const obj1 = { a: 1, b: '', c: [], d: null }
const obj2 = { a: 2, b: null, d: 1 }
let omitNull = obj => {
Object.keys(obj).filter(k => obj[k] === null).forEach(k => delete(obj[k]))
return obj
}
const result = { ...omitNull(obj1), ...omitNull(obj2) }
console.log(result)
答案 1 :(得分:2)
要添加到此良好答案列表中,这是一个适用于嵌套结构的递归解决方案。
此示例将在所有嵌套级别中将dst
对象的公共属性合并到src
对象,而保留所有不常见的属性。
const merge = (dst, src) => {
Object.keys(src).forEach((key) => {
if (!dst[key]) {
dst[key] = src[key];
} else if (typeof src[key] === 'object' && src[key] !== null && typeof dst[key] === 'object' && dst[key] !== null) {
merge(dst[key], src[key]);
}
});
},
/* Usage: */
src = {
prop1: '1',
prop2: {
val: 2,
}
},
dst = {
prop1: null,
prop2: {
val: null,
},
prop3: null,
};
merge(dst, src);
console.log(dst);
答案 2 :(得分:1)
如果您仅对两个对象的第一级感兴趣,则可以执行以下操作:
const obj1 = {
a: 1,
b: '',
c: [],
d: null
}
const obj2 = {
a: 2,
b: null,
d: 1
}
const merged = Object.keys(obj1).concat(Object.keys(obj2)) // create an array that contains the keys of the two objects.
.filter((k, i, arr) => arr.indexOf(k) === i) // remove duplicate keys
.reduce((a, c) => {
a[c] = obj1[c] !== null ? obj1[c] : obj2[c];
return a;
}, {});
console.log(merged);
此示例仅检查null
的值,您应该将其扩展为检查undefined
,空字符串等其他值。
答案 3 :(得分:1)
您使用Object.assign
做到了这一点,只是删除了之前不需要的内容
Object.keys(obj1).forEach( k => {
if ( obj1[k] //write the condition you want
delete obj1[k]
});
答案 4 :(得分:1)
您可以使用_.mergeWith()
,并且在合并回调中,如果不是null
,则仅取第二个值:
const obj1 = { a: 1, b: '', c: [], d: null }
const obj2 = { a: 2, b: null, d: 1 }
const result = _.mergeWith({}, obj1, obj2, (o, s) => _.isNull(s) ? o : s)
console.log(result)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
答案 5 :(得分:1)
const obj1 = {"a":1,"b":"","c":[],"d":null}
const obj2 = {"a":2,"b":null,"d":1}
const objMerged = _.create(
_.omitBy(obj1, _.isNull),
_.omitBy(obj2, _.isNull)
)
console.log(objMerged)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
答案 6 :(得分:1)
这是一个基于JS的纯解决方案:
遍历第一个对象以替换第二个对象中的值,然后添加第二个对象中的其他值。
const obj1 = {
a: 1,
b: '',
c: [],
d: null
}
const obj2 = {
a: 2,
b: null,
d: 1
}
function mergeObjs(obj1, obj2){
const merged = {}
keys1 = Object.keys(obj1);
keys1.forEach(k1 => {
merged[k1] = obj2[k1] || obj1[k1]; // replace values from 2nd object, if any
})
Object.keys(obj2).forEach(k2 => {
if (!keys1.includes(k2)) merged[k2] = obj[k2]; // add additional properties from second object, if any
})
return merged
}
console.log(mergeObjs(obj1, obj2))
答案 7 :(得分:1)
var objMerged = {};
for (var kobj1 in obj1) {
for (var kobj2 in obj2) {
if (obj1[kobj1] == null && obj2[kobj1] != null)
objMerged[kobj1] = obj2[kobj1];
else if (obj2[kobj2] == null && obj1[kobj2] != null)
objMerged[kobj2] = obj1[kobj2];
}
}
//打印obj合并显示