我有两个对象,我想从源更新目标对象值,但只更新目标中已存在的值。
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是否有这方面的功能?如果不是如何以一种好的方式解决它?
答案 0 :(得分:2)
一个简单的递归函数可以:
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;
}
答案 1 :(得分:0)
您需要遍历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
进行检查。
答案 2 :(得分:0)
您可以通过检查对象来采取递归方法。
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; }
答案 3 :(得分:0)
另一种ES6方法
<强>非变化的:强>
const intersector = (target = {}, source = {}) => {
return Object.keys(source).reduce((acc, prop) => {
if (target.hasOwnProperty(prop)) {
if (typeof source[prop] === 'object' && source[prop] !== null) {
acc[prop] = intersector(target[prop], source[prop]);
}
else {
acc[prop] = source[prop];
}
}
return acc;
}, {});
}
<强>变化的:强>
const intersector = (target = {}, source = {}) => {
return Object.keys(source).reduce((acc, prop) => {
if (target.hasOwnProperty(prop)) {
if (typeof source[prop] === 'object' && source[prop] !== null) {
acc[prop] = intersector(target[prop], source[prop]);
}
else {
acc[prop] = source[prop];
}
target[prop] = acc[prop];
}
return acc;
}, target);
};
答案 4 :(得分:0)
您可以结合使用Array.reduce()
和Object.keys()
ES6功能来实现:
let target = {
a: 1,
b: 2,
c: {
c_a: 3,
c_b: 4,
}
}
let source = {
a: 10,
c: {
c_a: 30,
c_d: 50,
},
d: 60
}
const assignOnlyIntersection = (sourceObj, targetObj) => {
return Object.keys(targetObj).reduce((intersection, key) => {
intersection[key] = (typeof targetObj[key] === 'object') ? assignOnlyIntersection(sourceObj[key], targetObj[key]) : sourceObj[key] || targetObj[key];
return intersection;
}, {})
}
target = assignOnlyIntersection(source, target);
console.log(target);