JS递归修改树状结构

现有一个树状结构,未知层数

const tree = [{
  id: 1,
  children: [{
    id: 11,
    children: [{
      id:111,
      children: [{
        id:1111,
        children: []
      }]
    }]
  }]
}]

一个树节点索引,索引也未知长度(索引长度总是小于树状层数的)
const index = [0,0,0]

一个新的值
const newValue = [{id: 222, children: []}]

期望:修改tree[0].children[0].children[0].children的值,优美的实现
就像这样:tree[0].children[0].children[0].children = newValue

补充:递归得到对应节点是获取,之后仍需要修改节点的值,最好是修改的原数据

阅读 4.3k
2 个回答

这哪里需要递归,不就是遍历递进处理么?一个循环

function assign(nodes, indexes, newChildren) {
    const node = indexes.reduce(
        (parent, idx) => parent?.children[idx],
        { children: nodes }
    );

    if (node) {
        node.children = newChildren;
    }

    // 有可能指定的索引数组没找到 node,这时候返回 undefined,方便外面判断
    return node;
}

assign(tree, index, newValue);
function traverse(treeShapeArray, indexArray) {
    if (indexArray.length === 0) {
        return treeShapeArray
    }

    const [index, ...rest] = indexArray
    return traverse(treeShapeArray[index].children, rest)
}

traverse(tree, [0, 0, 0])

我本来还只是以为你要取那个层级的数据,上面在 indexArray.length === 0 时修改确实改不掉,如果想要修改原数据,可以如下写:

traverse(tree, [0, 0, 0], [{id: 222, children: []}])

function traverse(treeShapeArray, indexArray, newChildren) {
  if (indexArray.length === 1) {
      treeShapeArray[indexArray[0]].children = newChildren 
      return
  }

  const [index, ...rest] = indexArray
  traverse(treeShapeArray[index].children, rest, newChildren)
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏