以缩进的方式展现 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 脚本》。
英文版