我有以下2个JavaScript对象:
let o1 = {
entities: {
1: {
text: "fooo",
nested: {
ids: [1, 2, 3],
flag: true
}
}
}
};
let o2 = {
ids: [4, 5, 6]
}
我希望在不改变它们的情况下合并它们,以获得一个看起来像这样的Object:
let o3 = {
entities: {
1: {
text: "fooo",
nested: {
ids: [1, 2, 3, 4, 5, 6],
flag: true
}
}
}
};
可能有n entities
,但只有entityId
定义的那个应该受到影响。
我尝试了什么:
let entityId = 1;
let o3 = Object.assign({}, o1, {
entities: Object.assign({}, o1.entities, {
[entityId]: Object.assign({}, o1.entities[entityId].nested,
{ ids: [...o1.entities[entityId].nested.ids, ...o2.ids] }
)
})
});
问题是text: "fooo",nested:
完全消失了。
我的方法是对的吗?这段代码可以优化吗?
答案 0 :(得分:3)
由于您标记了Redux,我将假设您使用的是React,并建议您使用不变性助手 - https://facebook.github.io/react/docs/update.html
您的代码如下所示:
let o3 = update(o1, {
entities: {
[entityId]: {
nested: {
ids: {
$push: [4, 5, 6]
}
}
}
}
})
<强> ES6 强>
您的逻辑是正确的,但您错过了代码中的nested
对象:
let o3 = Object.assign({}, o1, {
entities: Object.assign({}, o1.entities, {
[entityId]: Object.assign({}, o1.entities[entityId], {
nested : Object.assign({}, o1.entities[entityId].nested ,{
ids: [...o1.entities[entityId].nested.ids, ...o2.ids] })
}
)
})
});
答案 1 :(得分:0)
如果您知道您的数据不包含任何日期或方法,则可以使用JSON深度克隆技巧:
let o3 = JSON.parse(JSON.stringify(o1));
Array.prototype.push.apply(o3.entities[1].nested.ids, o2.ids);
答案 2 :(得分:0)
嗯,你的第一个问题是:
{
[entityId]: Object.assign({}, o1.entities[entityId].nested,
您将o1.entities[1].nested
的值复制到键o3.entities[1]
中,从而丢失o1.entities[1]
中保留的对象中的其他键。
这很难看,因为正如其他评论所指出的那样,这不是很漂亮的代码。
当然,您希望(而且意味着)使用o1.entities[entityId]
。
但是,如果你只是对你当前感兴趣的o1
部分执行深副本,那么还有一个问题。{{1}将复制对象引用,而不是创建完全新鲜的对象。因此,如果您稍后修改Object.assign()
的值,您也会改变o3.entities[1].text
。
答案 3 :(得分:0)
您似乎错过了一层合并 - 您的示例代码包含entities.1.ids
而不是entities.1.nested.ids
。尝试
let entityId = 1;
let o3 = Object.assign(
{},
o1,
{
entities: Object.assign(
{},
o1.entities,
{
[entityId]: Object.assign(
{},
o1.entities[entityId],
Object.assign(
{},
o1.entities[entityId].nested,
{ ids: [...o1.entities[entityId].nested.ids, ...o2.ids] }
)
)
}
)
}
);
此时,您可能希望从每个Object.assign
调用中构建一些中间变量,这样您就可以更好地跟踪所有内容。
答案 4 :(得分:0)
我会做:
const merged = {
entities: {
[entityId]: {
text: o1.entities[entityId].text,
nested: {
ids: [...o1.entities[entityId].nested.ids, ...o2.ids],
flag: o1.entities[entityId].nested.flag
}
}
}
}