【问题标题】:Remove children From A Nested Array using Recursion使用递归从嵌套数组中删除子级
【发布时间】:2019-05-27 13:02:33
【问题描述】:

我希望能够从有子对象的数组中删除一个对象。我立即认为这是一项递归工作,但我无法让我的递归函数正常工作。我想过使用 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 累加器未定义,但我不确定为什么。它应该制作一个新数组。我在这里错过了什么?

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

【问题讨论】:

  • 您是要删除节点还是创建一个过滤掉节点的新数组
  • 制作一个过滤掉节点的新数组。
  • @danh 我去看看。
  • 再仔细看一下……具有id 属性的对象都没有子对象。因此,当您说remove the node and all children below 时,不清楚您要过滤什么。

标签: javascript


【解决方案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))

【讨论】:

  • 这就是我想要的。非常感谢。
  • 我差点忘了归还累加器。
  • 是的,很容易忘记这一点。
  • 非常感谢。非常感谢您在周日抽出时间帮助我。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-24
  • 2020-03-25
  • 1970-01-01
  • 2018-05-28
  • 1970-01-01
  • 2019-03-23
相关资源
最近更新 更多