本帖最后由 shaowu459 于 2024-6-6 14:00 编辑
示例1:将一列数据分组,标准是累计和≤120就分一组。
因为要从上到下累计求和,所以我们很自然可以想到使用SCAN函数实现。
然后可以使用XMATCH函数判断≤120的位置是第几个:
有了位置2,提取数组的前2行进行合并存储即可。同时,把原数组前2行使用DROP函数去掉。
下一次循环的时候,同样使用SCAN函数对剩余的数组累计求和:
同样判断≤120的位置,然后提取、合并、存储新结果、去掉数组的前3行:
有了上面的分析,我们就可以使用递归来完成这个任务。使用arr代表原数组和变化后的数组,使用res存储每次循环的结果。参考公式如下(公式都不是最优的,仅用于清晰说明思路):
- =LET(f,LAMBDA(f,arr,res,LET(s,XMATCH(120,SCAN(,arr,SUM),-1),IF(COUNT(arr),f(f,DROP(arr,s),VSTACK(res,ARRAYTOTEXT(TAKE(arr,s)))),res))),f(f,A1:A14,"结果"))
复制代码
公式简要说明如下:
=LET(
f, LAMBDA(f,
arr, 存储原数组和变化数组
res, 存储结果
LET(
s, XMATCH(
120, 匹配值
SCAN(, arr, SUM), 对arr累计求和
-1), s结果为从上到下≤120的最大值所处位置
IF(
COUNT(arr), 如果arr是错误值时COUNT结果为0,也即可以退出循环
f(f,
DROP(arr, s), 递归重新调用f,新参数为上次的arr去掉前s行
VSTACK(res, ARRAYTOTEXT(TAKE(arr, s))) 堆积上一步的res和本次前s行的合并结果
),
res 如果arr已经是错误值,则返回res结果
)
)
),
f(f, A1:A14, "结果")
)
如果需要堆积成多行多列的结果,可以参考如下公式,堆积部分稍作调整即可:
- =LET(f,LAMBDA(f,arr,res,LET(s,XMATCH(120,SCAN(,arr,SUM),-1),IF(COUNT(arr),f(f,DROP(arr,s),VSTACK(res,TOROW(TAKE(arr,s)))),res))),IFNA(DROP(f(f,A1:A14,0),1),""))
复制代码
|