[英]Update object in array from another object in array
In my code I have two arrays, first one contains multiple objects. 在我的代码中,我有两个数组,第一个包含多个对象。 While the second one is to store serialized form data (mapped to JSON).
第二个是存储序列化的表单数据(映射到JSON)。 So both arrays are having identical keys.
因此,两个数组都具有相同的键。
What I want to achieve is to update the values of an object in the original array based on the values of an object in new array dynamically, by ID in the object. 我要实现的是,通过对象中的ID根据新数组中对象的值动态地更新原始数组中对象的值。
Found some examples online but hard to get them to work. 在网上找到了一些示例,但很难使它们起作用。 Because most of them are showing either one level of objects but I'm working on complex nested objects in the array.
因为它们大多数只显示一级对象,但是我正在处理数组中的复杂嵌套对象。
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'
}
}
];
The expected outcome is the products
array now updated with the values from the second array. 预期的结果是
products
数组现在已使用第二个数组中的值更新。
Output:
[
{
Id: 1,
Name: 'Product1',
Attributes: {
Storage: 'Normal',
Size: 'Medium'
}
},
{
Id: 2,
Name: 'French Fries',
Attributes: {
Storage: 'Normal',
Size: 'Small'
}
}
]
You could take a Map
for the update items and iterate products
. 您可以为更新项目获取
Map
并迭代products
。
If an item is found for an update, take a recursive approach and iterate the entries and check if the value is an object, then iterate the nested properties. 如果找到要更新的项目,则采用递归方法并迭代条目并检查值是否为对象,然后迭代嵌套的属性。
If no nested object found update the property. 如果未找到嵌套对象,请更新属性。
This works for arrays as well. 这也适用于数组。
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; }
You can create a function which combine nested objects. 您可以创建一个组合嵌套对象的函数。 And then use
map()
and find()
to create combined array of objects. 然后使用
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.