和传统的程序设计语言不同,SPL中集合的应用非常普遍,实际上最常见的序列和序表等本质上都是集合,可以对它们进行真正的集合运算,从而大幅度提高开发效率和代码性能。因此,在使用SPL时,需要特别重视对集合概念的理解。
1 SPL中的序列与集合
SPL中,序列如同整数、字符串一样是非常常用的基本数据类型,也能进行相应的基本运算。从集合角度出发,SPL提供了两个集合A、B的交、并、联、差等基本运算符:A^B,A|B,A&B,A\B等。如果能够从这些运算开始深刻理解并熟练运用,解决问题时就能更主动地采用集合思维,从而充分利用已知的数据,思路更直接和简洁,方法也更加简易清晰。
下面的例子显示了如何利用集合运算来简化代码:
A | |
---|---|
1 | =demo.query("select EID, NAME, SURNAME, GENDER, STATE from EMPLOYEE") |
2 | =A1.select(GENDER=="M") |
3 | =A1.select(STATE=="California") |
4 | =A2^A3 |
5 | =A1.select(GENDER=="M" && STATE=="California") |
6 | =A2&A3 |
7 | =A1.select(GENDER=="M" || STATE=="California") |
8 | =A2\A3 |
9 | =A1.select(GENDER=="M" && STATE!="California") |
代码中,A4、A6、A8采用了集合运算,分别统计了California州的男员工、所有男性或者位于California州的员工、不在California州的男员工,形式上和A5、A7、A9的传统统计方式相比,明显简洁了很多。
但是,需要注意的是,A6与A7中虽然获得的员工资料一致,但结果中记录的顺序不同,如下所示:
造成这种情况的原因是,与数学上的集合不完全相同,SPL中的集合称为有序集合,是有次序的,同时也可以有重复的成员。序列、序表、排列等全都是这种有序集合。
A | |
---|---|
1 | [1,2,3,4] |
2 | [1,3,3,2] |
3 | =[1,2,3]==[1,3,2] |
上表中,A2中的序列有重复的成员,而A3中两个序列中成员顺序不同,直接比较时会认为它们不相等,结果为false:
另外,数学上集合的交并运算是可交换的,即A∩BºB∩A和A∪B º B∪A,但由于SPL中的集合是有序集合,因此交换律并不成立,交并运算的结果集合将以左操作数的次序为准。
A | |
---|---|
1 | [1,2,3] |
2 | [3,1,5] |
3 | =A1^A2 |
4 | =A2^A1 |
5 | =A1&A2 |
6 | =A2&A1 |
A3,A4,A5和A6中的计算结果依次如下:
由于SPL中的序列是有序集合,因此判断两个序列是否有同样成员不能简单地用比较符==,而要用函数A.eq(B):
A | |
---|---|
1 | =[1,2,3]==[3,2,1] |
2 | =[1,2,3]==[3,2,1].sort() |
3 | =[1,2,3].eq([3,2,1]) |
4 | =[1,2,3].eq([3,2,2]) |
5 | =[1,2,2,3].eq([3,2,1,2]) |
6 | =[1,2,2,3].eq([3,2,3,1]) |
A1与A2中判断两个序列是否相同,结果如下:
这是因为A2中[3,2,1]执行sort函数排序后,得到的结果是[1,2,3],次序也和A1一样了。
A3、A4、A5和A6分别都使用函数A.eq(B)来判断两个序列是否有着同样的成员,结果依次如下:
如果两个序列中的所有成员全相同,则称这两个序列互为置换列。特别的,如果序列中出现了重复的成员,那么它的置换列中,这个成员也需要有同样的重复数量。
2 循环函数
有了集合数据类型,许多针对集合中成员的运算就可以方便地一句写出来,不再需要编写循环代码了。