在嵌套数组中查找和替换

时间:2019-02-25 23:46:29

标签: javascript

我有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
})

2 个答案:

答案 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)

以下内容将为您提供一些有关如何解决此问题的提示,而无需提供最终答案。

两种方法

您可以采用两种方法来解决此问题:

  1. 实现一个findItemById(id)方法,该方法以递归方式遍历allItems来查找具有特定id的项目。然后,您可以为newItems中的每个条目调用该函数,并在找到后覆盖相关属性。

  2. 实现一个traverseItems(itemTree, callback)方法,该方法以递归方式遍历项目树的每个级别,然后对遇到的每个项目和子项目调用callback。然后,回调函数将检查该项目的ID是否与newItems中的ID匹配,如果匹配,则用newItems中的条目覆盖其属性。

社区

如果您考虑这两种方法,则很明显,这两种方法都需要递归遍历函数,该函数可以遍历allItems的所有层。因此,专注于正确使用该基本算法,然后可以在两者之间做出决定。 (提示:它们中的一个可能比另一个效率更高,但是对于小型数据集,这实际上并不重要)。