ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 649|回复: 22

[分享] 用LET和LAMBDA模拟for循环的小套路

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-3-2 17:12 | 显示全部楼层 |阅读模式
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 wanghan519 于 2024-3-2 17:17 编辑

在类似scheme的语言里,for循环本就是用let和lambda来写的,所以有下面这个小套路:
  1. =LET(f,LAMBDA(x,y,IF(x=0,DROP(y,1),f(x-1,VSTACK(y,x)))),f(5,""))
复制代码
1. 这句的意思类似
  1. ret = []
  2. for (i = 5; i > 0; i--) {
  3.     ret.push(i)
  4. }
复制代码
2. let定义了函数f,然后调用了f
3. 函数f定义了,参数x,用来存储状态的变化,类似上面for循环里的i,参数y,用来存储结果数组,类似上面的数组ret
4. 函数f里只有一个if,如果达到退出条件,比如上面x等于0时,直接返回结果y,否则以x-1为参数调用函数f,用vstack把当前x加入到结果数组的结尾处
5. 总的意思是,对参数x逐步减1,每次把x加入数组y的最后,直到x等于0时输出y
6. 至于这里的DROP,是在初始状态时VSTACK必须有个初始数据否则报错,所以最后要删掉这个空数据
7. 总的来说,LET f LAMBDA x y IF这些部分全都是固定的套路,只有VSTACK这里是具体的逻辑,用起来还算简单
8. 另外,之所以把结果放到参数里,而不是以结果的方式传递给下一步,是看尾递归优化时说,IF的最后一步只调用函数f而不进行其他操作时,有些语言会自动尾递归优化,避免栈的增长,这里不知道我理解的用的对不对,但不在乎这些细节,只是用这个固定的套路还是没问题的
9. 类似VSTACK的函数可以用类似动态数组的方式处理数据,比如VSTACK可以在数组头部尾部添加数据,连接数组,DROP可以从数组头部尾部弹出数据,TAKE可以从数组头部尾部获取数据。。。

很多地方理解的不到位,之所以说是“套路”,因为套路好像更能吸引人使用这些新函数,只有套路动人心啊
wps也能用这些函数了,很爽

评分

6

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-3-2 17:24 | 显示全部楼层
本帖最后由 miaojohn45 于 2024-3-2 18:07 编辑

和excel不通用,excel中需要把双参数lambda定义名称为f,然后调用定义的名称f写公式:=f(5,"")

第二参数控制循环结束的写法:
=LET(f,LAMBDA(x,y,IF(x=y,x,VSTACK(x,f(x-1,y)))),f(9,2))


根据数值大小自动选择增减循环:
=LET(f,LAMBDA(x,y,IF(x=y,x,VSTACK(x,f(x+IF(x>y,-1,1),y)))),f(1,9))

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-3-2 17:32 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-3-2 18:18 来自手机 | 显示全部楼层
miaojohn45 发表于 2024-3-2 17:24
和excel不通用,excel中需要把双参数lambda定义名称为f,然后调用定义的名称f写公式:=f(5,"")

第二参数 ...

我过去也是这么写,不需要参数y,但上面第8条,看过尾递归优化之后,我一般把每一步的结果放到参数里,或者说,if那一步里,我现在都是直接执行f而不把f放到计算,比如vstack里,因为在其他语言里,if语句里如果直接就一个f,这会符合尾递归优化的要求,栈不会增长,但f如果放到其他计算中就不会优化,Excel不知道有没有这回事,但for循环改成的递归本就应该可以尾递归优化,所以我也强迫症似的强迫自己这样写,而且这样当成一个套路,写的时候if里面直接就是个f,也方便套路

TA的精华主题

TA的得分主题

发表于 2024-3-2 20:22 | 显示全部楼层
在目前WPS还没有循环函数的情况下,很有意思,就是不知道WPS哪天推出循环函数。。。
另外,如果再举一两个实例,帖子就可以申精啦。。。

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-3-3 04:29 | 显示全部楼层
如图所示,左上两个代码都是计算1递归的加到1亿亿
左边是a.scm,不需要y,但if里最后一句是先递归调用f后加上x
右边是b.scm,把结果放入y,if里最后一句只有递归的调用f
运行时,a.scm内存占用会无限变大,直到占满,b.scm也运行不到头,但内存占用不变


动画.gif

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-3-3 05:06 | 显示全部楼层
虽然楼上演示了尾递归写法可能的好处,但一方面excel可能没有尾递归优化,另一方面,采用2楼写法,就不需要drop那里处理vstack初始值报错的问题了,似乎这种写法更适合excel公式
举个例子
从一列数据里,每次取一个,(这里可以加入各种处理)放入结果数组,最后输出结果
这种如果用2楼的写法就不需要drop,而且写起来简化很多


批注 2024-03-03 045716.jpg
a.jpg

TA的精华主题

TA的得分主题

发表于 2024-3-3 11:31 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-3-3 12:04 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-3-3 12:13 来自手机 | 显示全部楼层
本帖最后由 wanghan519 于 2024-3-3 12:48 编辑
橒♂蝣 发表于 2024-3-3 12:04
我怎么感觉缺少遍历,没有这个循环有什么意义呢


呃,仔细想想,确实大多情况大家用数组公式或自动填充就能解决问题,这种写法也没啥优势,只能说提供给熟悉循环的人一条思路
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-28 08:15 , Processed in 0.042972 second(s), 15 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表