使用递归从嵌套数组中删除子级

时间:2018-12-30 17:40:20

标签: javascript

我希望能够从具有子对象的对象数组中删除对象。我立即想到这是递归的工作,但是我无法使递归功能正常工作。我想到了使用reduce来重建数据结构,而无需删除想要删除的对象。该函数应接受两个参数,即嵌套对象的数组和一个Id。

我的要求是:删除节点和下面的所有子代。

乍看之下,这似乎很容易,但是我发现的挑战是删除一个孩子并保持整个数据结构完整。通过基于id的筛选来删除父级是微不足道的,但是嵌套的子级会带来问题。

我的数据结构如下:

const data = [{
  id: 'BFQEA1W2RK1YRETZ9343',
  name: 'Cover',
  activityId: 'BFQEA1W2RK1YRETZ9343',
  nodeType: 'activity',
  suppressed: true,
  hidden: true
},
{
  children: [
    {
      id: 'ZNRAE749BSD0CTGHY888',
      name: 'Consultants, Reviewers, and National Geographic Exploration',
      activityId: 'ZNRAE749BSD0CTGHY888',
      nodeType: 'activity',
      suppressed: false,
      hidden: false
    },
    {
      id: 'JZLS37EVZQM22H9Q4655',
      name: 'The National Geographic Approach',
      activityId: 'JZLS37EVZQM22H9Q4655',
      nodeType: 'activity',
      suppressed: false,
      hidden: false
    },
  ]
}
]

如果我将此Id(ZNRAE749BSD0CTGHY888)传递给函数,则我的预期数据结果应为:

const expected =  [{
  id: 'BFQEA1W2RK1YRETZ9343',
  name: 'Cover',
  activityId: 'BFQEA1W2RK1YRETZ9343',
  nodeType: 'activity',
  suppressed: true,
  hidden: true
},
{
  children: [

    {
      id: 'JZLS37EVZQM22H9Q4655',
      name: 'The National Geographic Approach',
      activityId: 'JZLS37EVZQM22H9Q4655',
      nodeType: 'activity',
      suppressed: false,
      hidden: false
    },
  ]
}
]

我的功能如下:

 findNode = (id, arr) => {
    return arr.reduce((a, item) => {
      // if (item.id === id) {
      //   console.log('here');
      //   return item;
      // }
      if (item.id !== id) {
        a.push(item);
      }
      if (item.children) {
        return this.findNode(id, item.children);
      }
    }, []);
  };

该函数的reduce累加器未定义,但是我不确定为什么。它应该制作一个新的数组。我在这里想念什么?

在我看来,这似乎可行,但失败了。也许我的方法完全不可行。我应该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

在您的代码中,您没有返回累加器。这就是为什么您变得不确定。并且没有理由要对未推送的项的子项进行递归,因此应将递归嵌套在if下。

您可以使用reduce()遍历根数组。如果ID匹配,则返回并继续。否则,您可以递归地将子项传递给过滤器,然后推入返回数组:

const data = [{id: 'BFQEA1W2RK1YRETZ9343',name: 'Cover',activityId: 'BFQEA1W2RK1YRETZ9343',nodeType: 'activity',suppressed: true,hidden: true},{children: [{id: 'ZNRAE749BSD0CTGHY888',name: 'Consultants, Reviewers, and National Geographic Exploration',activityId: 'ZNRAE749BSD0CTGHY888',nodeType: 'activity',suppressed: false,hidden: false},{id: 'JZLS37EVZQM22H9Q4655',name: 'The National Geographic Approach',activityId: 'JZLS37EVZQM22H9Q4655',nodeType: 'activity',suppressed: false,hidden: false},]}]


function filterID(id, data) {
  return data.reduce((arr, item) => {
    if (item.id != id) {
      if (item.children) item.children = filterID(id, item.children)
      arr.push(item)
    }
    return arr  // <<-- need to return the accumulator  
  }, [])
}
console.log(filterID("ZNRAE749BSD0CTGHY888", data))