8.6 KiB
TSL 数组、键表、矩阵样数据与集合运算
文档类型:语法主线 是否可直接用于生成代码:是 是否含可直接照写示例:是 是否含不可照写反例:否 遇到不确定时:先按本页候选页继续判断;13_resultset_and_filters.md、22_matrix_deep_dive.md、23_fmarray.md、14_ts_sql.md;仍不命中时回到语法路由中心 index.md;如果问题已经超出语法层,回到 TSL 总入口 ../index.md
这一篇收拢 array(...) 的扩展用法:顺序数组、字符串键表、嵌套数组、本页明确的矩阵样比较,以及 in / sqlin / union2 / intersect / minus / outersect 这类去重型集合关系。
本篇职责
回答“array(...) 在 TSL 里除了最普通的一维数组,还能怎样组织数据;哪些矩阵样写法属于本页文档明确形态;元素、子集、整行和行集合关系应该怎样判断”。
智能体数组/矩阵样数据判断流程
- 先判断需要顺序数组、字符串键表、嵌套数组、矩阵样比较,还是去重型集合关系。
- 普通容器优先从
array(...)起手;下标和键访问回看值语法页。 - 矩阵链式比较只照
::系列文档明确示例写,不要混用标量链式比较。 - 基础成员判断用
in/not in;整行存在判断用sqlin/not sqlin;去重型行集合并、交、差、对称差用union2/intersect/minus/outersect。 - 结果集过滤或 TS-SQL 查询需求分别跳转到 13_resultset_and_filters.md 或 14_ts_sql.md。
- 没有对应代码块时不要发明数组/矩阵样数据/集合关系写法。
核心规则
array(...)既可以写顺序数组,也可以写字符串键表。- 顺序数组下标从
0开始;字符串仍然从1开始。 array(...)可以继续嵌套,形成二维或矩阵样数据。- 矩阵链式比较
::>、::<、::<>、::==、::>=、::<=属于本页文档明确形态。 in/not in处理的是元素存在关系,以及左侧为数组时的子集关系。sqlin/not sqlin处理的是行存在关系;左侧要当成一整行去匹配右侧结果集。union2、intersect、minus、outersect都按“行”运算,而不是按单元格逐个运算。- 集合运算结果会折叠重复行;如果需求是保留重复记录,改看 13_resultset_and_filters.md。
- 当数据本身就是一维数组时,按行集合运算和按元素集合运算是一致的。
- 左侧是数组时,先判定需求语义:子集关系用
in,整行存在关系用sqlin。
可直接照写示例
基础数组与键表
顺序数组与字符串键表:
代码块身份:可直接照写示例
arr := array(10, 20, 30);
hash := array("Code": "0001", "Price": 12.3);
writeLn("ARR0=", arr[0]);
writeLn("ARR1=", arr[1]);
writeLn("HASH=", hash["Code"]);
结果说明:
arr[0] = 10arr[1] = 20hash["Code"] = "0001"
嵌套数组:
代码块身份:可直接照写示例
[r1, r2] := array((1, 2), (3, 4));
writeLn(r1[0]);
writeLn(r1[1]);
writeLn(r2[0]);
writeLn(r2[1]);
结果说明:
- 依次输出
1、2、3、4 - 说明
array((1, 2), (3, 4))这种嵌套数组写法可以按普通数组继续读取
代码块身份:输出片段
1
2
3
4
矩阵样比较
矩阵链式比较:
代码块身份:可直接照写示例
r := array(1, 2, -1) ::< array(2, 1, 0) ::< array(3, 2, 1);
writeLn(r[0]);
writeLn(r[1]);
writeLn(r[2]);
s := array(1, 2, -1) ::< 2 ::< array(3, 2, 1);
writeLn(s[0]);
writeLn(s[1]);
writeLn(s[2]);
结果说明:
array(1, 2, -1) ::< array(2, 1, 0) ::< array(3, 2, 1)的三个元素依次输出1、0、1array(1, 2, -1) ::< 2 ::< array(3, 2, 1)的三个元素依次输出1、0、0- 说明矩阵链式比较会按元素位置分别得到结果数组,并且可以和标量混用
in、not in、sqlin、not sqlin
in 既可以判断单个元素是否存在,也可以判断左侧数组是否是右侧结果集的子集:
代码块身份:可直接照写示例
writeLn(1 in array(1, 2, 2));
writeLn(1 in array(0, 2));
writeLn(1 in array((1), (2)));
writeLn(array(1, 2) in array(1, 2, 3, 4));
writeLn(array(1, 3) in array((1, 2), (3, 4)));
writeLn(array(1, 2) in array(1));
writeLn(1 not in array(0, 2));
结果说明:
1 in array(1, 2, 2)输出11 in array(0, 2)输出01 in array((1), (2))输出1array(1, 2) in array(1, 2, 3, 4)输出1array(1, 3) in array((1, 2), (3, 4))输出1array(1, 2) in array(1)输出01 not in array(0, 2)输出1
代码块身份:输出片段
1
0
1
1
sqlin 按整行判断左侧是否存在于右侧结果集中:
代码块身份:可直接照写示例
writeLn(1 sqlin array(1, 2));
writeLn(array(1, 2) sqlin array(1, 2, 3));
writeLn(array(1, 2) sqlin array((1, 2), (3, 4)));
writeLn(array(5, 6) not sqlin array((1, 2), (3, 4)));
结果说明:
1 sqlin array(1, 2)输出1array(1, 2) sqlin array(1, 2, 3)输出0array(1, 2) sqlin array((1, 2), (3, 4))输出1array(5, 6) not sqlin array((1, 2), (3, 4))输出1in看元素或子集sqlin看整行
行集合并、交、差、对称差
下面这组最小例子展示“按行运算”和“结果会折叠重复行”:
代码块身份:可直接照写示例
left_rows := array((1, 2), (1, 2), (2, 3));
right_rows := array((1, 2), (3, 4));
union_rows := left_rows union2 right_rows;
intersect_rows := left_rows intersect right_rows;
minus_rows := left_rows minus right_rows;
outersect_rows := left_rows outersect right_rows;
结果说明:
left_rows union2 right_rows共有三行:(1,2)、(2,3)、(3,4)left_rows intersect right_rows只有一行:(1,2)left_rows minus right_rows只有一行:(2,3)left_rows outersect right_rows有两行:(2,3)、(3,4)left_rows原本有两行相同的(1,2),但union2/intersect的结果都只保留一份,说明集合运算会折叠重复行
更大的四列结果集文档结果:
array((1,2,3,4),(2,3,4,5),(1,1,1,1)) union2 array((1,2,3,4),(3,4,5,6),(2,2,2,2))返回array((1,2,3,4),(2,3,4,5),(1,1,1,1),(3,4,5,6),(2,2,2,2))- 同一组输入下:
intersect返回array((1,2,3,4)) - 同一组输入下:
minus返回array((2,3,4,5),(1,1,1,1)) - 同一组输入下:
outersect返回array((2,3,4,5),(1,1,1,1),(3,4,5,6),(2,2,2,2))
和过滤运算的区别
- 集合运算先把数据当成“行集合”来看,再做包含、并交差。
- 过滤运算先保留“原结果集里的每一条命中记录”;因此重复行会保留下来。
- 需要“集合关系”时留在本页。
- 需要“从原表里筛出哪些行”时看 13_resultset_and_filters.md。
默认生成模板
按需求语义从下面两种模板中选择:
代码块身份:可直接照写示例
matched := 1 in array(1, 2, 3);
row_matched := array(1, 2) sqlin array((1, 2), (3, 4));
本页不生成的范围
- 专门的结果集过滤函数
- TS-SQL 查询与写回
- 更大范围的矩阵函数族
这些内容分别进入 13_resultset_and_filters.md、14_ts_sql.md、22_matrix_deep_dive.md 或 23_fmarray.md,不再外跳到原目录。
禁止项
- 不要把字符串下标按数组的
0起始规则来写;字符串索引回看 03_values_and_literals.md。 - 不要把矩阵链式比较
::...和标量链式比较混写成同一种语法。 - 不要把
in和sqlin当成同一个概念。 - 不要期待
union2保留重复行。 - 不要用集合运算去做“保留原始重复记录”的过滤任务。
- 不要把二维结果集默认当成“按元素逐个比较”的集合运算。
- 左侧数组要表达“这些值是否都属于右侧集合”时,用
in。 - 左侧数组要表达“这一整行是否存在于右侧结果集”时,用
sqlin。 minus表达集合差集;如果任务要求保留左侧原始重复次数,改走 13_resultset_and_filters.md 的过滤规则。- 不要在本页发明结果集过滤、TS-SQL 查询、写回语法或更大矩阵函数族。
- 不要把普通
array(...)自动升级成FMArray;只有任务明确命中时才进入 23_fmarray.md。