以缩进的方式展现 csv 中的层次关系

例题描述和简单分析

有 csv 文件 csv.csv,如下所示:

ID,MenuName,ParentID,isHidden,LinkURL

1,Company,NULL,False,/company

2,About Us,1,False,/company/aboutus

3,Mission,1,False,/company/mission

4,Team,2,False,/company/aboutus/team

5,Client 2,10,False,/references/client2

6,Client 1,10,False,/references/client1

7,Client 4,10,True,/references/client4

8,Client 5,10,True,/references/client5

10,References,NULL,False,/references

csv存储菜单关系,ParentID 表示上级 ID,现在要将其输出在控制台,规则如下:

1.按父子关系依次输出,用缩进代表父子关系;

2.按 isHidden 的值决定是否显示;

3.同级菜单按 MenuName 排序,结果如下:

.Company

....About Us

.......Team

....Mission

.References

....Client 1

....Client 2

解法及简要说明

方法1:递归

在集算器中编写脚本 p1.dfx,如下所示:


A

B

C

1

=file("csv.csv").import@ct()

2

=func(A3,A1.select(ParentID==null),1)

3

func


4


for A3

>if(B4.isHidden=="False",output(fill(".",B3*3-2)/B4.MenuName))

5



=A1.select(ParentID==B4.ID).sort(MenuName)

6



>if(C5.len()>0,func(A3,C5,B3+1))

简要说明:

A1   csv文件读成序表,添加列 level,初始值为空集

A2  调用 A3 子程序,参数分别为所有根节点,节点层数

A3  定义子程序

B4  循环 A3,A3 对应子程序的第一个参数

C4  若 B4 的 isHidden 值为 False,则在控制台输出按当前节点层数 B3 计算的 B3*3-2 个. 拼接 B4 的 MenuName 值

C5  找出下一层级的所有记录

C6  若 C5 的记录数大于 0,则调用 A3 子程序,参数分别为 C5,节点层数 +1

方法2:循环

在集算器中编写脚本 p1.dfx,如下所示:


A

1

=file("csv.csv").import@ct().derive([]:level)

2

>A1.switch(ParentID,A1:ID)

3

=A1.nodes@p(ParentID)

4

>A3.run(~.run(if(level==[],level=ParentID.level|MenuName)))

5

=A1.select(isHidden=="False").sort(level).(fill(".",level.len()*3-2)/MenuName)

6

>output(A5.concat@n())

简要说明:

A1   csv文件读成序表,添加列 level,初始值为空集

A2  主键 ID,外键 ParentID,自连接

A3  递归查找所有在外键 ParentID 中引用到的记录,返回根节点到当前子节点的引用路径

A4  遍历 A3 序列,遍历当前成员(序表),若 level 为空,则把 ParentID.level 并上 MenuName 的值赋予 level

A5  A1过滤出 isHidden 值为 False 的记录,再按 level 排序,再按要求把多个. 和 MenuName 的值拼成串

A6  在控制台输出 A5 按换行符拼接的串

JAVA 集成这段代码的方法可参考:《Java 如何调用 SPL 脚本》

问答搜集

https://stackoverflow.com/questions/62356935/read-from-csv-and-display-the-items-like-in-the-example-in-java