前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 、Kotlin、JavaScript 把全路径列表转换成树状层级嵌套结构

Java 、Kotlin、JavaScript 把全路径列表转换成树状层级嵌套结构

作者头像
一个会写诗的程序员
发布2020-02-13 13:44:07
1.1K0
发布2020-02-13 13:44:07
举报

问题描述

代码语言:javascript
复制
source:

 /a/b/c/d/e
 /a/b/e/f/g
 /a/b/h
 /a/i/j
 /a/i/k

what I need:

    e g

程序源代码

JavaScript

代码语言:javascript
复制
let treeDTO = [];
let array = [
    'a/b/c/d/e',
    'a/b/e/f/g',
    'a/b/h',
    'a/i/j',
    'a/i/k'
];

array.map((item) => {
    let key = item;             // key is the full path
    let nodeArray = key.split('/');           // split the full path with '/'
    // 递归
    let children = treeDTO;

    // 构建根节点
    if (children.length == 0) {
        let root = {
            key: nodeArray[0]
        };
        if (nodeArray.length > 1) {
            root.children = [];
        }
        children.push(root);
    } else {
        // 循环构建子节点
        for (let i in nodeArray) {
            console.log("i:" + i);
            console.log("nodeArray:" + nodeArray);

            let node = {
                key: nodeArray[i]
            };

            if (i != nodeArray.length) {
                node.children = [];
            }

            if (children.length == 0) {
                children.push(node);
            }

            let isExist = false;

            for (let j in children) {
                console.log("j:" + j);

                if (children[j].key == node.key) {
                    if (i != nodeArray.length - 1 && !children[j].children) {
                        children[j].children = [];
                    }
                    children = (i == nodeArray.length - 1 ? children : children[j].children);

                    console.log("children:" + JSON.stringify(children));

                    isExist = true;
                    break;
                }
            }

            if (!isExist) {
                children.push(node);
                if (i != nodeArray.length - 1 && !children[children.length - 1].children) {
                    children[children.length - 1].children = [];
                }
                children = (i == nodeArray.length - 1 ? children : children[children.length - 1].children);
            }

        }
    }
});

console.log(treeDTO);

/* source:
 /a/b/c/d/e
 /a/b/e/f/g
 /a/b/h
 /a/i/j
 /a/i/k

   what I need:

         a
       /   \
      b     i
     /|\   / \
    c e h j   k
    | |
    d f
    | |
    e g
*/

Java

节点是通用泛型数据模型:

代码语言:javascript
复制
import com.alibaba.fastjson.JSON;

import java.util.Arrays;

/**
 * @author: Jack
 * 2020-01-11 00:17
 */
public class Main {
    public static void main(String[] args) {
        Tree<String> forest = new Tree<String>("root");
        Tree<String> current = forest;

        for (String tree :
            Arrays.asList(
                "a/b/c/d/e",
                "a/b/e/f/g",
                "a/b/h",
                "a/i/j",
                "a/i/k")) {


            Tree<String> root = current;

            for (String data : tree.split("/")) {
                current = current.child(data);
            }

            current = root;

        }

        forest.accept(new TreeVisitor());

        System.out.println(JSON.toJSONString(forest));
    }
}


 
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * @author: Jack
 * 2020-01-11 00:13
 */
class Tree<T> implements Visitable<T> {
    // NB: LinkedHashSet preserves insertion order
    private Set<Tree> children = new LinkedHashSet<Tree>();
    private T data;

    Tree(T data) {
        this.data = data;
    }

    public void accept(Visitor<T> visitor) {
        visitor.visitData(this, data);

        for (Tree child : children) {
            Visitor<T> childVisitor = visitor.visitTree(child);
            child.accept(childVisitor);
        }
    }

    Tree child(T data) {
        for (Tree child : children) {
            if (child.data.equals(data)) {
                return child;
            }
        }
        return child(new Tree(data));
    }

    Tree child(Tree<T> child) {
        children.add(child);
        return child;
    }

    public Set<Tree> getChildren() {
        return children;
    }

    public void setChildren(Set<Tree> children) {
        this.children = children;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}


 
/**
 * @author: Jack
 * 2020-01-11 00:13
 */
interface Visitor<T> {

    Visitor<T> visitTree(Tree<T> tree);

    void visitData(Tree<T> parent, T data);
}

 

/**
 * @author: Jack
 * 2020-01-11 00:13
 */
interface Visitable<T> {

    void accept(Visitor<T> visitor);
}


 

/**
 * @author: Jack
 * 2020-01-11 00:15
 */
class TreeVisitor implements Visitor<String> {
    TreeVisitor() {
    }

    public Visitor<String> visitTree(Tree<String> tree) {
        return new TreeVisitor();
    }

    public void visitData(Tree<String> parent, String data) {
    }
}

Kotlin

自定义具体化的节点模型:

代码语言:javascript
复制
import java.util.*

/**
 * @author: Jack
 * 2020-01-11 02:35
 */
class NavTree : NavVisitable {
    var deptNo = ""
    var deptName = ""
    var hasPermission = false
    var leaf = false
    var children: MutableSet<NavTree> = LinkedHashSet()

    constructor(deptNo: String, deptName: String, hasPermission: Boolean, leaf: Boolean) {
        this.deptNo = deptNo
        this.deptName = deptName
        this.hasPermission = hasPermission
        this.leaf = leaf
    }


    /**
     * 递归遍历
     */
    override fun visit(visitor: NavVisitor) {
        visitor.visitTree(this)
        for (child in children) {
            val childVisitor = visitor.visitTree(child)
            child.visit(childVisitor)
        }
    }


    fun children(data: NavTree): NavTree {
        for (child in children) {
            if (child.deptNo == data.deptNo) {
                return child
            }
        }
        children.add(data)
        return data
    }
}


/**
 * @author: Jack
 * 2020-01-11 00:15
 */
class NavTreeVisitor : NavVisitor {

    override fun visitTree(tree: NavTree): NavVisitor {

        return NavTreeVisitor()
    }

}


/**
 * @author: Jack
 * 2020-01-11 00:13
 */
interface NavVisitable {
    fun visit(visitor: NavVisitor)
}


/**
 * @author: Jack
 * 2020-01-11 00:13
 */
interface NavVisitor {

    fun visitTree(tree: NavTree): NavVisitor
}


   /**
     * 构建导航树
     *  source:
    /a/b/c/d/e
    /a/b/e/f/g
    /a/b/h
    /a/i/j
    /a/i/k

    transform to:

    a
    /   \
    b     i
    /|\   / \
    c e h j   k
    | |
    d f
    | |
    e g
     */
    private fun buildAlibrainNavTree(authorizedDepts: List<DataPermissionDeptDTO>, hasPermissionDeptMap: MutableMap<String, DataPermissionDeptDTO>, deptInfoMap: MutableMap<String, String>): NavTree {
        // 顶级根节点
        var rootNode = NavTree(
                deptNo = "00001",
                deptName = "XXX",
                leaf = false,
                hasPermission = false
        )

        var current = rootNode

        authorizedDepts.map {
            val root = current
            val length = it.deptNoArray.size

            it.deptNoArray.forEachIndexed { index, e ->
                val data = NavTree(
                        deptNo = e,
                        deptName = deptInfoMap[e] ?: "",
                        leaf = (index == length - 1),
                        hasPermission = (hasPermissionDeptMap[e] != null)
                )
                current = current.children(data)
            }

            current = root
        }

        rootNode.visit(NavTreeVisitor())
        return rootNode
    }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题描述
  • 程序源代码
    • JavaScript
      • Java
        • Kotlin
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档