Javascript - 从树中递归删除某种类型的节点,但重新附加并传播符合条件的子节点

标签 javascript json recursion tree

我正在 JSON 树 {name, type, [children]} 上编写递归函数来删除特定类型的节点。但是,如果已删除节点的子节点不是要删除的类型,则应将其重新附加到父节点。

我遇到了以下困难: 假设我想删除以下树上的类型 b:

const sampleData = [{
name: "parent",
type: "a",
children: [{
    name: "childA",
    type: "a",
    children: null
    },{
    name: "childB",
    type: "b",
    children: [{
        name: "grandChildA",
        type: "a",
        children: null
        },{
        name: "grandChildB",
        type: "a",
        children: null
        }]
    },{
    name: "childC",
    type: "a",
    children: null
    }]
}]

父级的原始子级是[childA, childB, childC]。 删除后,父级应该有子级[childA, grandChildA, grandChildB, childC]。 但是,我得到的结果是 [childA, [grandChildA, grandChildB], childC]

我知道我需要将其展开,但我不确定在休会中的何处进行。

这是我现在拥有的函数(我知道我在错误的地方使用了扩展语法):

const removeType = (node, type) => {
    //if the node should not be removed    
    if (node.type !== type){
        //if the node has children, recursively call to prune children
        if (node.children && node.children.length > 0){
            node.children = [...node.children.map(child => removeType(child, type))
                                             .filter(child => child !== null)]
            return node
        }
        //if the node has no children, return the node
        else return node
    }
    //if the node should be removed
    else if (node.type === type){
        //if the node has children, recursively call, then reattach the children
        if (node.children && node.children.length > 0){
            node.children = [...node.children.map(child => removeType(child, type))
                                             .filter(child => child !== null)]
            return node.children
        }
        //
        else return null
    }
}

最佳答案

已更新

我认为你可以使用reduce来实现这一点,我现在没有电脑来测试它,但它会是这样的

const removeType = (node, type) => {
   if (node === null) {
     return null;
   } else {
    return node.reduce((acc, child) => {
      if(child["type"] === type) {
        const removedChild = removeType(child["children"], type);
        acc = [...acc, ...removedChild];
      } else {
        child.children = removeType(child["children"], type);
        acc.push(child);
      }
      return acc;
    }, []);
  }
}

第二次更新

代码减少:

const removeType = (node, type) => {
    if (!node) return;

    return node.reduce((acc, child) => {
        if(child["type"] === type) {
            const removedChild = removeType(child["children"], type);
            acc = [...acc, ...removedChild];
        } else {
            child.children = removeType(child["children"], type);
            acc.push(child);
        }
        return acc;
    }, []);

}

关于Javascript - 从树中递归删除某种类型的节点,但重新附加并传播符合条件的子节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63759347/

相关文章:

PHP 从数据库中提取数据时将所有非英文字符替换为 null

json - 无法在 React 应用程序中访问来自 Express 服务器的响应数据

python - 列表python列表的递归最大函数

javascript - 我们需要使用 javascript 来创建响应式布局吗?

javascript - 创建带有导出的模板

javascript - 从特定类文本创建数组

javascript - 使用四元数在 Three.js 中将平移/倾斜 Angular 转换为 XYZ?

java - 如何使用 "org.json"包中的类将对象序列化为 JSON 字符串?

python - 将路径列表转换为python中的字典

scala - 无法优化@tailrec注释的方法循环: it contains a recursive call not in tail position