javascript - 使用 JavaScript reduce 更新并添加到对象数组
问题描述
我正在尝试解决 JavaScript 中的一个问题,并相信使用该reduce
方法将是最优雅的。我有一组看起来像这样的对象:
let existingLots = [
{
id: 1,
title: 'one',
colour: 'red',
speed: 100
},
{
id: 2,
title: 'two',
colour: 'blue',
speed: 70
},
{
id: 3,
title: 'three',
colour: 'white',
speed: 120
},
{
id: 4,
title: 'four',
colour: 'yellow',
speed: 90
},
]
另一个看起来像这样的数组:
let newLots = [
{
id: 1,
title: 'one',
colour: 'orange',
speed: 100,
owner: 'Ted'
},
{
id: 2,
title: 'two',
colour: 'blue',
speed: 75
},
{
id: 3,
title: 'three updated',
colour: 'white',
speed: 120,
},
{
id: 4,
title: 'four',
colour: 'yellow',
speed: 90
},
{
id: 5,
title: 'five',
colour: 'green',
speed: 50
},
]
如您所见,一些 id 之间存在重叠。我想更新existingLots
数组,以便如果一个对象与数组id
中的一个共享相同newLots
,则该对象将使用其对应对象中的任何新属性/值进行更新newLots
。另外,我希望将不在其中的任何对象newLots
(即带有id
of 的对象)添加到数组中。5
existingObjects
existingObjects
我尝试了以下方法,但没有达到预期的结果:
const res = existingLots.reduce((acc, obj) => {
let updatedObj = newLots.filter(newLot => newLot.id === obj.id);
// if object exists in currentLots, merge it
if(updatedObj) {
[...acc, {...obj, ...updatedObj}]
} else {
let newObj = !newLots.filter(newLot => newLot.id === obj.id);
[...acc, {...newObj}]
}
return acc
}, [])
我是 JavaScript 数组方法的新手,因此不胜感激。
解决方案
1) You are using filter which will return an array of filter elements
The filter() method creates a new array with all elements that pass the test implemented by the provided function. - MDN
2) This code just push/add all objects after the last element in the array and then discarded since you are not storing them anywhere
[...acc, {...obj, ...updatedObj}]
SOLUTION: You can use forEach to loop over the newLots
array and add data to existingLots
element
newLots.forEach((newLot) => {
let objExist = existingLots.find((o) => o.id === newLot.id);
if (objExist) {
for (let key in newLot) objExist[key] = newLot[key];
} else existingLots.push(newLot);
});
or
newLots.forEach((newLot) => {
let index = existingLots.findIndex((o) => o.id === newLot.id);
if (index !== -1) existingLots[index] = { ...existingLots[index], ...newLot };
else existingLots.push(newLot);
});
let existingLots = [
{
id: 1,
title: "one",
colour: "red",
speed: 100,
},
{
id: 2,
title: "two",
colour: "blue",
speed: 70,
},
{
id: 3,
title: "three",
colour: "white",
speed: 120,
},
{
id: 4,
title: "four",
colour: "yellow",
speed: 90,
},
];
let newLots = [
{
id: 1,
title: "one",
colour: "orange",
speed: 100,
owner: "Ted",
},
{
id: 2,
title: "two",
colour: "blue",
speed: 75,
},
{
id: 3,
title: "three updated",
colour: "white",
speed: 120,
},
{
id: 4,
title: "four",
colour: "yellow",
speed: 90,
},
{
id: 5,
title: "five",
colour: "green",
speed: 50,
},
];
newLots.forEach((newLot) => {
let index = existingLots.findIndex((o) => o.id === newLot.id);
if (index !== -1) existingLots[index] = { ...existingLots[index], ...newLot };
else existingLots.push(newLot);
});
console.log(existingLots);
推荐阅读
- ruby-on-rails - 在 Rails 方法中的特定点跳过授权
- angularjs - angularjs 外部控制器文件导致错误“未定义角度”
- google-sheets - 为非 GMT 时区调整 toDate(now())
- javascript - 当输入的单词正确时,向 javascript 添加声音以播放
- ios - UITableView 单元格中的镜像以进行本地化
- c - 读取文件长度错误
- java - 微调器 onItemSelected 没有调用
- java - getNumberOfCameras() 总是返回 0
- c - 打印数组指针的C函数?
- datatables - 使用可见错误的数据表不起作用