我有2个结构不同的数组,我想检查allItems
并替换newItems
中存在的任何内容。我尝试使用map
,但不确定如何处理嵌套的对象数组。
const allItems = [
{
'id': 1,
'text': 'old',
'child': [
{
'id': 2,
'text': 'old'
}
]
}
]
const newItems = [
{
'id': 1,
'text': 'new',
'more_info': 'abcd'
},
{
'id': 2,
'text': 'new',
'more_info': 'abcd'
}
]
我想返回:
{
'id': 1,
'text': 'new',
'more_info': 'abcd',
'child': [
{
'id': 2,
'text': 'new'
'more_info': 'abcd'
}
]
}
]
我的代码(这与子级别无关)
const result = allItems.map(x => {
const item = newItems.find(({ id }) => id === x.id)
return item ? item : x
})
答案 0 :(得分:1)
child
属性仅表示一个,但是这种选择循环了整个数组。
您可以使用递归来更深入并通过id
更新找到的对象。
这种方法会变异原始数组
const allItems = [{ 'id': 1, 'text': 'old', 'child': [ { 'id': 2, 'text': 'old' } ]}],
newItems = [ { 'id': 1, 'text': 'new', 'more_info': 'abcd' }, { 'id': 2, 'text': 'new', 'more_info': 'abcd' }]
looper = (arr, items) => {
arr.forEach(outer => {
let found = items.find(n => outer.id === n.id);
if (found) {
Object.assign(outer, found);
if (outer.child) looper(outer.child, items);
}
});
};
looper(allItems, newItems);
console.log(allItems);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:1)
以下内容将为您提供一些有关如何解决此问题的提示,而无需提供最终答案。
您可以采用两种方法来解决此问题:
实现一个findItemById(id)
方法,该方法以递归方式遍历allItems
来查找具有特定id
的项目。然后,您可以为newItems
中的每个条目调用该函数,并在找到后覆盖相关属性。
实现一个traverseItems(itemTree, callback)
方法,该方法以递归方式遍历项目树的每个级别,然后对遇到的每个项目和子项目调用callback
。然后,回调函数将检查该项目的ID是否与newItems
中的ID匹配,如果匹配,则用newItems
中的条目覆盖其属性。
如果您考虑这两种方法,则很明显,这两种方法都需要递归遍历函数,该函数可以遍历allItems
的所有层。因此,专注于正确使用该基本算法,然后可以在两者之间做出决定。 (提示:它们中的一个可能比另一个效率更高,但是对于小型数据集,这实际上并不重要)。