关于 A.pos(x) 位置返回的问题
根据官方文档描述,A.pos(x)的其中一个作用是 "获取序列中成员在另一个序列中的位置",比如,序列 [1,3] 在序列 [null,1,2,3,null] 中的位置,返回的结果是[2,4],如下:
现在改一下,变成序列 [1,3] 在序列 [null,1,2,3,null,3,1] 中的位置,此时序列 A 中有多个 1 和 3,而我想返回的结果是 [2,4,6,7],那 A.pos(x) 就无法直接返回所有的位置,该功能没有 @a 选项,此时返回的结果依然是[2,4],如下所示:
而具有 @a 选项,能返回所有位置结果的,是 pos 的另一个功能 "获取序列成员位置序号",可以通过以下写法变相实现:
这样一来就变成序列循环了,没有那么直接。所以,我在想官方可否实现 A.pos@a(x) 返回序列 x 中所有成员在序列 A 中的所有位置。以下是用 Power Query 模拟需要实现的结果,供参考:
以上需求拓展,恳请 SPL 大佬们考虑一下,或者有没有其他更优雅的方式实现,谢谢!
早上好,老贼😄 感谢指点解惑🙏
1、我对 A.pos(X) 的概念理解的不是很透彻,按您所说,返回完整子序列在主序列中的位置,子序列可能有很多,结果集可能会很大,这样我就懂了。发帖求助有点草率了,下次,我得注意改一下求助的方式方法,不能这个拓展,那个完善,见谅;
2、我有点 "形而上" 了,看问题只看了表面,这个用法具体用在哪里也没有真实落地的场景。促使我发帖求助的原因一个是同 PQ 的类比,当时学习 pos 的时候也一直存在这个困扰,怎么没有返回子序列中对应元素的所有位置的写法;再一个是有群友问了如何删除序列中的指定的元素,比如删除序列 [null,1,2,3,null,3,1] 中的元素 1 和 3,得到[null,2,null],这个解法我能想到的有两种:select 或者 delete,但 delete 好像没有直接删除元素的写法,不管操作对象是序列还是序表,要么按位置删除,delete(位置集),要么按筛选出来的值删除,delete(select 结果集),而且 select 和 delete 有本质区别,前者是 immutable,后者是 mutable(这样说不知道对不对),我感觉按位置删除效率是很高的(目前,我对写法效率的高低仍依靠测试和感觉,没有理论体系支持),所以就有了 pos@a 这个写法的需求。哈哈,基本就是这样的心路历程,肤浅了。
3、您用 pselect 的写法,明显比 [1,3].conj([null,1,2,3,null,3,1].pos@a(~)) 要高明,虽然我讲不出好在哪里,但感觉后者的时间复杂度很高(依然靠感觉,哈哈),学习了,谢谢!
Have a nice day! Peace!
还有一点:
A.pos@c(x) @c 选项的说明是这样的,“返回序列 x 在 A 中第一次出现的位置,以便求序列 A 中子序列 x 出现的位置,若 x 不是 A 的子序列则返回空”,这里我觉得会有点困惑,实际上使用 @c 选项时,要求 x 是 A 的子数组,子数组是特殊的子序列,必须是连续的,也就是说此时 x 应该是 A 中的某个连续的片段,才能求出 x 出现的位置,而子序列是无序的,只要保证子序列中的元素都存在于主序列 A 中即可,但 SPL 中没有数组的概念,只有序列,不知道这样说是不是正确?
对功能理解没错。
数组就是序列。SPL 没有严格定义什么叫子序列,就是通俗的理解(“子”的“序列”)。这里文档写得不太清楚,写成连续子序列会好一些。但自己试试也知道是什么意思了。