【问题标题】:How to edit tree structure?如何编辑树结构?
【发布时间】:2021-08-25 09:46:43
【问题描述】:

树形结构是这样的-

const init = [
    {
        name: 'A',
        children: [
            {
                name: 'A1',
                children: []
            },
            {
                name: 'A2',
                children: [
                    {
                        name: 'A21',
                        children: []
                    }
                ]
            }
        ]
    },
    {
        name: 'B',
        children: [
            {
                name: 'B1',
                children: []
            },
            {
                name: 'B2',
                children: []
            }
        ]
    }
]

我有变量

  1. currentPath = ['A', 'A2', 'A21']
  2. node = { name: 'A211', children: [] }

我想将 init 转换为

const init = [
    {
        name: 'A',
        children: [
            {
                name: 'A1',
                children: []
            },
            {
                name: 'A2',
                children: [
                    {
                        name: 'A21',
                        children: [
                            {
                                name: 'A211',
                                children: []
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        name: 'B',
        children: [
            {
                name: 'B1',
                children: []
            },
            {
                name: 'B2',
                children: []
            }
        ]
    }
]

请告诉我我需要使用什么函数funcAppendNode(init, currentPath, node) 接受init、currentPath 和新节点并返回新的init。我认为它与递归有关,但我无法成功。

这是我迄今为止尝试过的。

const funcAppend = (init, currentPath, node) => {
    let newState = [...init]
    for (let i = 1; i < currentPath.length; i++) {
        newState = newState.find(o => o.name === currentPath[i]).children
    }
    newState.push(node)
    return newState
}

上面的函数正在返回 [ { name: 'A211', children: [] } ]

请帮忙。

【问题讨论】:

    标签: javascript arrays recursion ecmascript-6 functional-programming


    【解决方案1】:

    const init = [{
        name: 'A',
        children: [{
            name: 'A1',
            children: []
          },
          {
            name: 'A2',
            children: [{
              name: 'A21',
              children: []
            }]
          }
        ]
      },
      {
        name: 'B',
        children: [{
            name: 'B1',
            children: []
          },
          {
            name: 'B2',
            children: []
          }
        ]
      }
    ];
    
    const currentPath = ['A', 'A2', 'A21'];
    const node = {
      name: 'A211',
      children: []
    };
    
    let target = {
      children: init
    };
    currentPath.forEach(path => {
      target = target.children.find(child => child.name === path);
    });
    target.children.push(node);
    console.log(init);
    .as-console-wrapper {
      top: 0;
      max-height: 100% !important;
    }

    【讨论】:

    • 你能添加一个描述你做了什么来完成这个吗?显然,您反复遍历范围并更新了目标,但 TL;DR 至少会有所帮助。
    【解决方案2】:

    我会这样处理问题:

    1. 从您的 names 数组中,构建您的树路径
    2. 在树路径上,只需附加新节点

    const toTreePath = ([head, ...tail], data) => {
      const index = data.findIndex((node) => node.name === head);
      const next = data[index]?.children;
      
      return [index, 'children'].concat(
        next?.length ? toTreePath(tail, next) : []
      );
    };
    
    const append = (node, path, data) => {
      const $path = toTreePath(path, data);
      
      return R.over(
        R.lensPath($path),
        R.append(node),
        data,
      );
    }
    
    
    // ======
    
    const newNode = 'HELLO WORLD';
    const path = ['A', 'A2', 'A21'];
    
    const data = [
      {
        name: 'A',
        children: [
          {
            name: 'A1',
            children: []
          },
          {
            name: 'A2',
            children: [
              {
                name: 'A21',
                children: []
              }
            ]
          }
        ]
      },
      {
        name: 'B',
        children: [
          {
            name: 'B1',
            children: []
          },
          {
            name: 'B2',
            children: []
          }
        ]
      }
    ];
    
    console.log(
      append(newNode, path, data),
    );
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla+YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous" referrerpolicy="no-referrer"&gt;&lt;/script&gt;

    【讨论】:

      【解决方案3】:

      我同意递归...所以首先,您要查找退出条件...即path.length = 1。你知道在这种情况下该怎么做。

      如果退出条件不满足,你应该调用函数传递一组新的参数,“reduced”。

      作为与您类似的示例,我决定将节点添加到项目中的所有路径(不仅仅是第一个)。

      appendNode(items, path, node) {
        if (path.length === 1) {
          for (item in items.filter(item => item.name = path[0])) {
            item.children.push(node)
          }   
        } else {
          const firstElement = path.shift(); //removed the first element from path
          for (item in items.filter(item => item.name = firstElement)) {
            addNode(item.children, path, node)
          }
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-04-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-24
        • 2015-12-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多