我有两个对象,我想要更新源中的目标对象值,但只更新目标中已经存在的值。
const target = {
a: 1,
b: 2,
c: {
c_a: 3,
c_b: 4,
}
}
const source = {
a: 10,
c: {
c_a: 30,
c_d: 50,
},
d: 60
}
const result = assignOnlyIntersection(target, source);
JSON.stringify(result)
// {
// a: 10,
// b: 2,
// c: {
// c_a: 30,
// c_b: 4
// }
// }
在ES6中有解决这个问题的好方法吗?如果没有,lodash有这样的功能吗?如果不是,如何才能很好地解决它呢?
发布于 2017-10-29 21:29:17
一个简单的递归函数就可以做到:
function assignOnlyIntersection(target, source) {
if (Object(target) !== target || Object(source) !== source)
return source;
for (const p in source)
if (p in target)
target[p] = assignOnlyIntersection(target[p], source[p]);
return target;
}
发布于 2017-10-29 20:41:58
您需要遍历target
对象的键,检查source
对象上是否有相同的键,如果有,则替换该值。如果你在途中发现了一个对象,你也需要递归。
下面这样的代码就可以完成这项工作:
const target = { a: 1, b: 2, c: { c_a: 3, c_b: 4 }};
const source = { a: 10, c: { c_a: 30, c_d: 50 }, d: 60 };
function assignOnlyIntersection(t, s) {
Object
.keys(s)
.filter(k => k in t)
.forEach(k => {
if (typeof t[k] === 'object') {
assignOnlyIntersection(t[k], s[k]);
} else {
t[k] = s[k];
}
});
return t;
}
const result = assignOnlyIntersection(target, source);
console.log(JSON.stringify(result));
还要注意的是,如果您想要支持替换为0
或''
之类的假值,则需要使用typeof t[k] !== 'undefined'
检查是否存在。
正如@ghybs指出的,如果你也想支持用undefined
值替换,你需要通过in
operator k in t
来检查。
发布于 2017-10-29 21:47:15
您可以通过检查对象来采用递归方法。
function deepAssign(target, source) {
Object.keys(source).forEach(function (k) {
var objectCount = [source, target]
.map(o => o[k])
.map(o => o && typeof o === 'object')
.map(Boolean)
.reduce((a, b) => a + b)
if (!(k in target) || objectCount === 1) {
return;
}
if (objectCount === 2) {
return deepAssign(target[k], source[k]);
}
target[k] = source[k];
});
return target;
}
var source = { a: 10, c: { c_a: 30, c_d: 50, }, d: 60 },
target = { a: 1, b: 2, c: { c_a: 3, c_b: 4, } };
console.log(deepAssign(target, source));
.as-console-wrapper { max-height: 100% !important; top: 0; }
https://stackoverflow.com/questions/47000238
复制相似问题