在我的代码中,我有两个数组,第一个包含多个对象。第二个是存储序列化的表单数据(映射到JSON)。因此,两个数组都具有相同的键。
我要实现的是,根据对象中的ID,根据新数组中对象的值动态更新原始数组中对象的值。
在网上找到了一些示例,但很难使它们起作用。因为它们大多数只显示一级对象,但是我正在处理数组中的复杂嵌套对象。
var products = [
{
Id: 1,
Name: 'Product1',
Attributes: {
Storage: 'Normal',
Size: 'Small'
}
},
{
Id: 2,
Name: 'Product2',
Attributes: {
Storage: 'Normal',
Size: 'Small'
}
}
];
var newData = [
{
Id: 2,
Name: 'French Fries'
},
{
Id: 1,
Attributes: {
Size: 'Medium'
}
}
];
预期结果是products
数组现在已使用第二个数组中的值更新。
Output:
[
{
Id: 1,
Name: 'Product1',
Attributes: {
Storage: 'Normal',
Size: 'Medium'
}
},
{
Id: 2,
Name: 'French Fries',
Attributes: {
Storage: 'Normal',
Size: 'Small'
}
}
]
答案 0 :(得分:3)
您可以将Map
用于更新项目,并迭代products
。
如果找到要更新的项目,则采用递归方法并迭代条目,并检查值是否为对象,然后迭代嵌套的属性。
如果未找到嵌套对象,请更新属性。
这同样适用于数组。
function update(target, source) {
Object.entries(source).forEach(([key, value]) => {
if (value && typeof value === 'object') {
update(target[key] = target[key] || (Array.isArray(value) ? [] : {}), value);
} else if (target[key] !== value) {
target[key] = value;
}
});
}
var products = [{ Id: 1, Name: 'Product1', Attributes: { Storage: 'Normal', Size: 'Small' } }, { Id: 2, Name: 'Product2', Attributes: { Storage: 'Normal', Size: 'Small' } }],
newData = [{ Id: 2, Name: 'French Fries' }, { Id: 1, Attributes: { Size: 'Medium' } }],
map = new Map(newData.map(o => [o.Id, o]));
products.forEach(o => map.has(o.Id) && update(o, map.get(o.Id)));
console.log(products);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:0)
您可以创建一个组合嵌套对象的函数。然后使用map()
和find()
创建对象的组合数组。
var products = [
{
Id: 1,
Name: 'Product1',
Attributes: {
Storage: 'Normal',
Size: 'Small'
}
},
{
Id: 2,
Name: 'Product2',
Attributes: {
Storage: 'Normal',
Size: 'Small'
}
}
];
var newData = [
{
Id: 2,
Name: 'French Fries'
},
{
Id: 1,
Attributes: {
Size: 'Medium'
}
}
];
const haveNested = obj => Object.values(obj).some(x => typeof x === "object");
function combine(obj1,obj2){
if(!haveNested(obj1)) return ({...obj1,...obj2})
let res = obj1
for(let key in obj1){
if(typeof obj1[key] === "object"){
res[key] = combine(obj1[key],obj2[key]);
}
else if(obj2[key]) res[key] = obj2[key]
}
return res;
}
const result = products.map(x => {
let temp = newData.find(a => a.Id === x.Id);
return temp ? combine(x,temp) : x;
})
console.log(result)