javascript递归数组递归问题

发布于 2022-09-05 02:45:18 字数 716 浏览 18 评论 0

现在有个需求,需要根据服务端请求的数据,组装成一个树节点,也就是parent-child节点,服务端请求后的数据结构如下图,topology是一个object,object下面的key是一个parent,value是child数组。

图片描述

var topology = {1:['2'],2:['29','39','38','37'],24:['27'],29:['24'],37:['42'],38:['43'],39:['47'],42:['46'],43:['45']}

比如上图中的1有一个child是一个数组["2"],这个value为2的child又有4个child,也就是["29","39","38","37"]

最终需要生成如下数据结构,即key是parent的string,child因为有多个,所以是一个数组

const data = {"1":{"2":{"29":{"24":{"27":["26"]}},"39":["47"],"38":{"43":["45"]},"37":{"42":["46"]}}}}

再次先谢过了。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

裸钻 2022-09-12 02:45:18
var topology = [ ... ];

function rebuildTopo(index) {
    var topo = topology[index];
    var check = false;
    
    if(!topo) {
        return null;
    } else if(topo instanceof Array) {
        var obj = {};
        
        for(var j in topo) {
            var t = topo[j];
            obj[t] = rebuildTopo(t);
            
            if(!!obj[t])
                check = true;
        }
        
        if(check)
            return obj;
        else
            return Object.keys(obj);
    }
}

console.log(JSON.stringify({1: rebuildTopo(1)}));

结果:
clipboard.png

Update

针对你所说的结构,又写了一段:

var topology = [ ... ];

function rebuildTopo(index) {
    var topo = topology[index];
    
    if(!topo) {
        return {key: index};
    } else if(topo instanceof Array) {
        var obj = {};
        
        obj.key = index;
        obj.children = topo.map(function(v, i) {
            return rebuildTopo(v);
        });
        
        return obj;
    }
}

console.log(JSON.stringify(rebuildTopo(1)));

不得不说,新的数据结构反而更容易理解,也更加容易写。当然,其实!topo判断和topo instanceof Array判断可以合并,写作

function rebuildTopo(index) {
    var topo = topology[index];

    var obj = {};
    
    obj.key = index;
    obj.children = (topo || []).map(function(v, i) {
        return rebuildTopo(v);
    });
    
    return obj;
}

后者略有区别,当子元素不存在时候也会有children: [],而前者由于分开判断了!topo,所以子元素不存在就不会有children项。

紙鸢 2022-09-12 02:45:18

你要生成的数据应该是这种形式吧:

{
  key: '1',
  children: [{
    key: '2',
    children: [...]
  }]
}
function appendChildren (data, key = '1') {
  const node = { key }
  if (Array.isArray(data[key])) {
    node.children = data[key].map(child => appendChildren(data, child))
  }
  return node
}
↘紸啶 2022-09-12 02:45:18

@cool_zjy 多谢。
是的,需要你这种数据结构,问题描述里没有写清楚,抱歉。
现在这个递归后的数据,需要塞入到antd的treenode里面,也就是每个parent需要由child组成Treenode,比如这样(举个例子,children节点没有全部写出来)。

        <TreeNode title="1" key="1">
          <TreeNode title="2" key="2">
            <TreeNode title="29" key="29">
                <TreeNode title="24" key="24">
                    <TreeNode title="27" key="27">
                        <TreeNode title="26" key="26" />
                    </TreeNode>
                </TreeNode>
            </TreeNode>
            <TreeNode title="39" key="39">
                <TreeNode title="47" key="47" />
            </TreeNode>
            <TreeNode title="38" key="38">
                <TreeNode title="43" key="43">
                    <TreeNode title="45" key="45" />
                </TreeNode>
            </TreeNode>
            <TreeNode title="37" key="37">
                <TreeNode title="42" key="42">
                    <TreeNode title="46" key="46" />
                </TreeNode>
            </TreeNode>
          </TreeNode>
        </TreeNode>

这个是官方文档,以下代码是我的实现(参考了官方文档里的异步数据加载部分的代码),不过报错了。
https://ant.design/components...

                const appendChildren = (data, key = '1') => {
                    const node = { key }
                    if (Array.isArray(data[key])) {
                        node.children = data[key].map(child => appendChildren(data, child))
                    }
                    return node
                }
                const firstKey = Object.keys(topology)[0];   //这里的topology是服务端返回的数据
                const result = [appendChildren(topology,firstKey)];
                const loop = data => data.map((item) => {
                    if (item.children) {
                        return <TreeNode title={item.key} key={item.key}>{loop(item.children)}</TreeNode>;
                }
                    return <TreeNode title={item.key} key={item.key} />;
                });
                this.setState({treeData:loop(result)});

报错提示:

TreeNode.js:382 Uncaught (in promise) TypeError: props.filterTreeNode is not a function
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文