论 Reduce 与 Lambda 递归:谁是盟主?
做表格的人,迟早会撞上“循环”这道墙。过去,要在 Excel 里按行做累计、把多行合并成一段话、或者处理树形目录,常规方案只有三个:VBA 宏、辅助列、手动拉公式。现在,Excel 365 和 WPS 新版本带来了REDUCE和LAMBDA,很多人第一次发现:原来表格公式也能写“递归”,也能做“循环”。
但也正因为这两个函数太接近,社区里经常争论一个问题:REDUCE和LAMBDA递归,到底谁才是核心?有人说REDUCE是真正的循环之王,有人说LAMBDA能自己调用自己,才是底层逻辑。我的判断是:这不是一场“谁替代谁”的竞争,而是一次“循环调度”和“函数式编程能力”的分工合作。在日常业务汇总里,REDUCE是更安全、更好用的那个;在复杂拆解和树形结构面前,LAMBDA递归才是真正的“能力盟主”。但无论用哪一个,终止条件、循环深度和底层执行逻辑,才是决定公式能不能稳定跑完的根本问题。
这篇文章不打算只罗列函数语法。我会先用一组可复制的公式,把REDUCE和LAMBDA递归的差异拆开,再重点讲清楚终止条件的写法、循环深度踩坑点,以及它们在 Excel/WPS 计算引擎下的真实行为。看完之后,你至少能回答三个问题:什么时候该用REDUCE?什么时候只能上递归?递归卡死、报错、循环深度超限时,第一步到底该查哪里?
1. 这篇文章真正要解决的问题
先说说你大概率的真实体验。学会了REDUCE之后,你会觉得它像一个“数据流水线”:给定一个初始值,再给一个处理规则,它就能把一个数组逐项“折叠”成结果。可等你进一步接触LAMBDA递归,又发现函数居然能调用自己,仿佛打开了新世界。于是问题来了:同样能实现循环效果,为什么REDUCE有时候也会卡死?为什么递归写到一定深度就报#NUM!?为什么在 WPS 里同一个公式可能直接#NAME??
这些问题背后,其实是三个层面的混淆:
- 语法层面:
REDUCE只是“折叠工具”,它依赖LAMBDA实现每轮计算;LAMBDA是“函数定义工具”,它本身不强求递归。 - 执行层面:
REDUCE的循环由函数内部引擎驱动,数组耗尽就自动停止;LAMBDA递归的循环由用户自己写终止条件,漏写就是死循环。 - 工程层面:
REDUCE在大多数业务场景里够用,且心智负担低;LAMBDA递归功能更强,但循环深度、调试难度都更苛刻。
这篇文章的核心任务,就是把这三点讲透。文章的重点不是让你二选一,而是让你掌握“什么时候该用什么”,以及“怎么写出不会把工作簿跑死的公式”。如果你正在被公式嵌套层级困扰,或者想把 Excel 公式写出编程思路,这篇文章值得读完。
2. 基础概念与核心原理
在动手写公式之前,先把三个核心概念对齐。很多人读不懂嵌套公式,不是英语问题,而是没有建立“函数是一个运算单元”的心智模型。
2.1 REDUCE:传送带上的加工台
REDUCE的语法是:
=REDUCE(初始值, 要遍历的数组, LAMBDA(累计变量, 当前值, 处理逻辑))你可以把REDUCE想象成一条传送带:传送带上按顺序放着数组里的每个元素,初始状态由第一个参数指定;LAMBDA则是传送带旁边的一个加工台,每次处理一个元素,加工的结果作为一个新的“累计变量”,继续参与下一轮加工。
例子:
=REDUCE(0, A1:A5, LAMBDA(acc, v, acc + v))如果 A1:A5 是 1、2、3、4、5,执行过程是这样的:
- 第 1 轮:acc = 0,v = 1,结果 = 1
- 第 2 轮:acc = 1,v = 2,结果 = 3
- 第 3 轮:acc = 3,v = 3,结果 = 6
- 第 4 轮:acc = 6,v = 4,结果 = 10
- 第 5 轮:acc = 10,v = 5,结果 = 15
注意,REDUCE的循环次数完全由数组长度决定。数组有多少个元素,它就执行多少轮。引擎处理完最后一个元素,自动停止。这个“自动停止”非常重要,它是REDUCE稳定性的来源。
2.2 LAMBDA:自定义函数的最小单元
LAMBDA的语法是:
=LAMBDA(参数1, 参数2, ..., 计算表达式)(参数1的值, 参数2的值, ...)例如:
=LAMBDA(x, x * 2)(10)结果是 20。LAMBDA的价值不在于它能在单元格里写一次性公式,而在于可以配合名称管理器,定义一个真正可复用的“自定义函数”。你在名称管理器里新建一个名称,比如DOUBLE,引用位置写=LAMBDA(x, x * 2),之后在表格里直接输入=DOUBLE(10),结果同样是 20。
这是 Excel/WPS 公式历史上一个分水岭:表格从此不再只有内置函数,用户自己也能定义函数了。也就是说,LAMBDA是“编程能力”的基础设施,REDUCE、MAP、SCAN这些函数只是建立在这个基础设施之上的“调度器”。
2.3 递归:函数自己调用自己
递归是一种程序技巧:函数在运行过程中调用自身。它有两个关键要素:
- 递推方向:每一次调用都要让问题规模变小,比如
n-1、去掉数组的第一个元素。 - 终止条件:当问题规模小到某个边界时,直接返回结果,不再调用自己。
在 Excel/WPS 中,普通单元格公式很难直接写递归,因为公式里不知道怎么“引用自己”。最常见的做法是:在名称管理器里定义一个有名字的LAMBDA,在这个LAMBDA的函数体内部引用这个名字。
举个例子,定义一个阶乘函数:
=LAMBDA(n, IF(n <= 1, 1, n * FACT_REC(n - 1)))这里FACT_REC是名称,引用位置正是这条LAMBDA公式。调用=FACT_REC(5)时,函数体内部又调用了FACT_REC(4),依次类推,直到n=1时通过终止条件返回 1。这个过程就是递归。
2.4 REDUCE 与 LAMBDA 递归的本质区别
很多初学者看到REDUCE的LAMBDA每轮都会执行,就以为它是递归。其实不是。REDUCE是“迭代”,它只是反复调用一个普通函数,调用过程中没有形成“自己调用自己”的调用栈。而LAMBDA递归会不断压栈:每一层递归都保留着上一层还没算完的中间状态,直到触发终止条件再逐层返回。
两者的关键差异可以用表格总结:
| 对比维度 | REDUCE | LAMBDA 递归 |
|---|---|---|
| 循环驱动者 | 函数引擎遍历数组 | 函数体内部调用自身 |
| 终止条件 | 数组元素耗尽,自动停止 | 用户用 IF 等条件手动控制 |
| 循环深度 | 取决于数组长度和引擎计算上限 | 取决于调用栈深度,更容易触发限制 |
| 中间状态 | 只有一个累加器,天然保存状态 | 递归栈分布在各层调用中 |
| 调试难度 | 相对低,逻辑在一个函数体内 | 相对高,出错时定位较麻烦 |
| 典型场景 | 累加、拼接、去重、状态表 | 树形结构、无限嵌套、数学分形 |
简单来说,REDUCE是“循环调度官”,LAMBDA是“函数定义引擎”,而LAMBDA递归则是“程序员亲手写循环”。在实际工作里,能用REDUCE解决的循环,通常优先用REDUCE;只有当问题本身需要“拆开一层再拆开一层”时,递归的优势才会真正体现。
3. 环境准备与前置条件
这节课会用到REDUCE、LAMBDA、VSTACK、SEQUENCE等函数。它们不是老版本 Excel 都有的,所以先检查环境。
3.1 软件版本
- Excel:建议使用 Microsoft 365 订阅版,也就是经常说的人人版或企业版。旧版 Excel 2016、2019 大概率没有
REDUCE。 - WPS:较新版本的 WPS 表格已经支持
LAMBDA、REDUCE等函数,但不同版本的支持情况有差异。如果你用的是老版本 WPS,可能直接提示#NAME?。
版本细节建议以你实际安装版本为准。判断标准很简单:在单元格里输入下面这个公式,如果返回 1,说明当前环境支持LAMBDA:
=LAMBDA(x, x)(1)再输入下面这个公式,如果返回 7,说明支持REDUCE:
=REDUCE(1, {1, 2, 3}, LAMBDA(a, b, a + b))3.2 名称管理器与命名 LAMBDA
递归示例需要在“名称管理器”中定义名称。操作路径:
- Excel:公式选项卡 -> 名称管理器 -> 新建
- WPS:公式选项卡 -> 名称管理器 -> 新建
名称管理器界面里有两个关键输入框:
- 名称:比如
FIB、NUM_TO_STR - 引用位置:完整的
=LAMBDA(...)公式
定义完成后,就能在单元格中以普通函数的形式调用它。需要说明的是,名称管理器里定义的公式,修改后要重新计算工作簿才会生效。
3.3 建议先备份数据
REDUCE和递归公式通常只做计算,不会直接修改单元格数据,但如果公式引用的是全列,比如A:A,一旦逻辑写错或递归没有终止条件,可能导致工作簿长时间计算,严重时卡死。建议在测试阶段复制一份数据或使用小范围区域测试。
4. 核心流程拆解:循环、迭代与递归
既然要论谁是盟主,先得把“循环到底怎么写”的流程拆明白。这一章用四个小步骤,带你从REDUCE到递归走一遍。
4.1 用 REDUCE 构建“表格式循环”
假设要把 B 列若干非空单元格用顿号拼接成一个字符串。传统写法是用TEXTJOIN一把梭,但为了理解REDUCE,我们先自己写一个“累加器”:
=REDUCE("", B2:B10, LAMBDA(acc, v, IF(v = "", acc, acc & IF(acc = "", "", "、") & v)))这个公式的流程是:
- 初始值是一个空字符串
""。 - 每遍历到一个单元格,如果单元格为空,累加器不变;如果非空,就把当前值拼到累加器后面。
- 为了不出现“、张三、李四”这种开头多一个顿号的情况,用
IF(acc = "", "", "、")判断是不是第一个非空值。
这就是典型“表格式循环”的流程:遍历 → 判断 → 更新累加器 → 进入下一轮。整个过程由REDUCE引擎负责,不需要写退出条件。
4.2 用 LAMBDA 递归实现“函数式循环”
再看同一个问题如果用递归怎么写。先把问题拆解成最小单元:拼字符串本质上是在做“取第一个非空值,拼到结果,然后继续处理剩下的数据”。如果能在名称管理器里定义一个JOIN_TEXT名称:
=LAMBDA(value_array, IF(COUNT(value_array) = 0, "", ...))这里需要先判断数组是否为空。但 Excel 公式里“判断数组是否为空”本身是一个很麻烦的操作,所以通常的递归练习不会从字符串拼接开始。更合适的递归入门问题是“把一个整数按位拆成字符串”,这个我们放到第 5 章完整实现。这里先记住关键点:递归必须自己做两件事,一是缩小问题规模,二是判断边界。
4.3 终止条件的两个来源
对比REDUCE和递归,终止条件其实是两种完全不同的东西:
REDUCE的终止条件藏在引擎里。数组遍历完,循环自然结束。你不需要在LAMBDA里写“如果数组结束就退出”,因为引擎根本不给你这个控制权。LAMBDA递归的终止条件掌握在你自己手里。你必须显式写出 IF 分支,告诉函数“什么时候不要再调用自己”。
这也是递归最容易出问题的地方。很多新手写递归时,只想着“怎么往下拆”,忘了“拆到什么时候停”。递归一旦没有终止条件,结果就是一个永无休止的调用链,最终触发#NUM!或工作簿卡死。
4.4 循环深度问题出在哪
REDUCE的循环次数等于数组长度。理论上,你给REDUCE一个 5000 行的数组,它就可能执行 5000 轮。但这不意味着它能无限循环,因为它依赖数组的实际大小,并且整个公式本身也要参与 Excel 的计算链,运算量过大同样可能让 Excel 卡顿。
LAMBDA递归则不同,它每一次调用自身都会形成一层调用栈。类似其他编程语言中的“递归深度”概念,Excel/WPS 公式环境对递归深度是有上限的。超过这个上限,公式就会返回错误。常见的表现是:小数据量测试正常,数据量稍微变大,突然报#NUM!。这通常就是递归深度超限,而不是你的逻辑写错了。
所以在工程上,有一个很实用的建议:能用迭代解决的问题,尽量不要用递归;如果只能用递归,先用小规模数据测试出当前环境的深度边界,再决定数据范围。
5. 完整示例与代码实现
现在进入正题,用四个可直接复制的示例,把REDUCE和LAMBDA递归的典型用法串起来。所有公式都以 Excel/WPS 单元格或名称管理器引用位置为准。
5.1 示例一:REDUCE 多行合并去重
场景:A 列有很多文本,有些重复,需要把所有非空不重复的值用顿号拼接起来。如果只拼不进行去重,可以直接用TEXTJOIN,但这里为了演示REDUCE的累加器能力,我们手动维护一个“已存在字符串”的集合。在单元格中输入:
=REDUCE("", A2:A20, LAMBDA(acc, v, IF(v = "", acc, IF(ISNUMBER(SEARCH(v, acc)), acc, acc & IF(acc = "", "", "、") & v))))关键逻辑拆解:
SEARCH(v, acc)在当前已拼接的结果里查找当前值是否存在。如果找得到,说明已经出现过,累加器保持不变;如果找不到,就把当前值拼接进去。- 用
,分隔符时要注意,如果原始文本本身包含逗号,这个判断可能误伤。实际业务中更推荐用UNIQUE先做去重,再拼接:
=TEXTJOIN("、", TRUE, UNIQUE(A2:A20))这个示例真正的意义是:让你看到acc累加器不只是“数字加和”,它可以是一个字符串、一个状态、甚至一个能描述业务逻辑的线索。理解这一点,REDUCE才算真正入门。
5.2 示例二:LAMBDA 递归把整数转换成字符串
这个例子对应经典的“递归法将一个整数 n 转换成字符串”问题。在 Excel/WPS 里,我们用名称管理器定义一个递归函数NUM_TO_STR。
第一步:打开名称管理器,新建名称:
- 名称:
NUM_TO_STR - 引用位置:
=LAMBDA(n, IF(n < 0, "-" & NUM_TO_STR(-n), IF(n < 10, CHAR(48 + n), NUM_TO_STR(INT(n / 10)) & CHAR(48 + MOD(n, 10)))))第二步:在任意单元格输入:
=NUM_TO_STR(12345)预期结果是文本"12345"。
这个递归函数怎么理解?
- 如果
n是负数,先加一个负号,再递归处理它的绝对值。 - 如果
n是一位数,直接返回字符。CHAR(48 + n)利用 ASCII 码把数字 0-9 转成字符"0"-"9"。 - 否则,把
n整除 10,递归得到前面所有位的结果;再用MOD(n, 10)取出最后一位。比如n=123,先递归NUM_TO_STR(12)得到"12",再拼上CHAR(48 + 3)得到"123"。
这里的终止条件就是n < 10。每一次递归都让n变成INT(n / 10),数字位数逐渐减少,最终一定进入终止条件。如果漏掉这个判断,公式会一直调用自己,直到系统报错。
还要注意一点:这个函数假设输入的是整数。如果输入123.45,MOD和INT的行为会导致结果不符合预期。实际使用前建议先对数据做整数化处理。
5.3 示例三:REDUCE 状态表求斐波那契数列
斐波那契数列是递归教材的常客,但恰恰它也是“递归性能差”的典型。用公式递归求第 30 项都可能让工作簿明显变慢,因为同一项会被重复计算很多次。
先看递归写法。在名称管理器中新建名称FIB_REC:
=LAMBDA(n, IF(n <= 1, n, FIB_REC(n - 1) + FIB_REC(n - 2)))调用:
=FIB_REC(10)结果是 55。逻辑很漂亮,但性能很差。n 稍大就会明显变慢,而且递归深度问题也会很快出现。
更推荐的做法是用REDUCE维护一个“状态表”。斐波那契的迭代逻辑是:从{0, 1}开始,每一轮都把状态更新成{后一个数, 前两个数之和}。在单元格中输入:
=IF(A1 = 0, 0, IF(A1 <= 2, 1, INDEX(REDUCE({0;1}, SEQUENCE(A1 - 1), LAMBDA(acc, v, VSTACK(INDEX(acc, 2), SUM(acc)))), 2)))这里假设A1是要求的第 n 项,并且 n 从 1 开始计数。执行过程:
REDUCE的初始值是一个两行一列的数组{0;1}。- 每次循环,
acc变成{旧状态的第二个元素;旧状态两个元素之和}。 - 循环结束后,用
INDEX(..., 2)取出第二行,也就是第 n 项。
注意IF(A1 <= 2, 1, ...)是为了拦截 n=1 和 n=2 的情况,因为此时SEQUENCE(0)可能产生空数组,不同版本表现不一样。这个细节也印证了:即使是REDUCE这样“自带终止条件”的函数,写边界判断时依然要谨慎。
5.4 示例四:递归深度和 REDUCE 循环深度测试
为了让你直观感受两者的循环深度差异,可以写两组测试公式。
先建一个递归计数器。名称管理器中新建名称DEPTH_TEST:
=LAMBDA(n, IF(n <= 0, 0, DEPTH_TEST(n - 1) + 1))然后分别调用:
=DEPTH_TEST(100) =DEPTH_TEST(1000) =DEPTH_TEST(3000)你会发现,小数字没问题,但到达一定深度后,公式会报错。具体上限与你的 Excel/WPS 版本、公式复杂度有关,社区常见说法是递归深度大致在 1000 层左右就会触发限制。不要把这个数字当作绝对阈值,重点是用这个公式测试出你自己环境的边界。
再看REDUCE的循环深度:
=REDUCE(0, SEQUENCE(5000), LAMBDA(acc, v, acc + 1))如果返回 5000,说明REDUCE处理 5000 轮迭代没有问题。这个测试简单粗暴,但能说明一件事:REDUCE的循环次数受限于数组大小和整体计算量,而不是“函数调用栈”那种严格限制。不过数据量继续放大到数万、数十万行时,性能一定会下降,这是由 Excel/WPS 的计算引擎决定的。
6. 运行结果与效果验证
写了公式之后,怎么判断结果对不对、流程是否走通?这一章给出快速验证方法。
6.1 名称管理器录入验证
以示例二为例,确认录入正确的方式:
- 打开名称管理器,查看
NUM_TO_STR的引用位置是否完整,注意以=开头。 - 任意单元格输入
=NUM_TO_STR(0),预期返回文本"0"。这一步可以验证终止条件是否有效。 - 输入
=NUM_TO_STR(12345),预期返回"12345"。如果返回#NAME?,说明名称没定义成功或名称拼写错误。 - 输入
=NUM_TO_STR(-123),预期返回"-123"。这一步验证负数分支。
如果上面四个测试都通过,递归函数的正确性基本有保证了。
6.2 REDUCE 结果验证
示例一测试时,建议先用三个值做最小样本。假设 A2:A4 分别是“张三”“李四”“张三”,公式应该返回“张三、李四”。如果返回“张三、李四、张三”,说明去重逻辑失效,重点检查SEARCH是否被原始数据里的特殊字符干扰。
示例三测试时,先代入A1=1、A1=2、A1=10,预期分别是 1、1、55。任何一个异常,都先检查IF分支是否覆盖边界,再检查INDEX取的是哪一行。REDUCE返回的是一个两行数组时,不要直接在工作表单元格里显示,因为多行数组会溢出到相邻单元格,务必用INDEX取值。
6.3 怎么判断“递归没停”
递归最大的风险是“公式不报错,但永远在计算”。如果调用递归函数后,Excel/WPS 长时间显示正在计算,大概率是递归没有终止条件,或者条件永远无法满足。此时可以采取三个措施:
- 按 Esc 尝试中断计算。
- 检查递归函数的 IF 分支,确保存在一个不需要再调用自身的路径。
- 用非常小的输入值测试,例如从 0、1、2 开始,逐步增大,观察在哪一个值开始异常。
7. 常见问题与排查思路
下面的表格汇总了REDUCE和LAMBDA递归最常见的问题,适用于快速排查:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
公式返回#NAME? | 当前 Excel/WPS 版本不支持REDUCE/LAMBDA,或名称管理器中的名称未定义成功 | 先测试=LAMBDA(x,x)(1)是否返回 1;检查名称管理器是否存在名称 | 升级软件版本;重新定义名称并检查拼写 |
递归公式报#NUM!或#VALUE! | 递归没有终止条件,或循环深度超过环境上限 | 用小型输入逐步测试;检查 IF 分支是否覆盖边界 | 补全终止条件;把递归改写成REDUCE迭代 |
| 公式长时间不返回结果 | 递归调用失控,或REDUCE遍历范围过大 | 按 Esc 中断;检查引用区域是否包含整列 | 限制数据范围;使用小型测试区域 |
REDUCE结果比预期少一项或多一项 | 初始值设置错误,或LAMBDA累加逻辑有误 | 在纸上画出acc每轮变化;用 3 个元素的小样本测试 | 调整初始值;修正LAMBDA内部拼装逻辑 |
| 拼接去重结果误判 | SEARCH通配符干扰,或原始文本互相包含 | 改用UNIQUE+TEXTJOIN做对照测试 | 业务场景优先用UNIQUE;教学场景保留现有逻辑 |
WPS 中不支持VSTACK或SEQUENCE | WPS 版本对部分新函数支持不完整 | 检查函数是否报#NAME? | 升级 WPS 版本;使用辅助列替代 |
注意,#NAME?在 WPS 中非常常见。很多用户明明在 Excel 里跑得好好的公式,粘贴到 WPS 就失效,原因通常是 WPS 版本较旧,或者某个新函数没有被当前 WPS 版本收录。遇到这类问题,优先查看版本而不是反复改公式逻辑。
8. 最佳实践与工程建议
REDUCE和LAMBDA递归都是非常强大的工具,但如果直接在真实工作簿里大规模使用,建议遵守下面几条工程规则。
8.1 能用 REDUCE 优先用 REDUCE
除非问题本身就是“一层套一层”的嵌套结构,否则优先用REDUCE。理由有三点:
REDUCE自带终止条件,数组遍历完就停,不容易写出“死循环”。REDUCE只有一个累加器,中间状态在明面上,调试更容易。REDUCE与日常表格思维更贴近,其他同事接手时更容易理解。
如果确实需要递归,也要先考虑是否能转化成REDUCE+ 状态表。斐波那契数列就是典型的“递归可以写,但迭代更好”的例子。
8.2 递归三要素必须写全
一次正确的LAMBDA递归,至少要具备三要素:
- 参数推进:每次递归调用,参数都要向着终止条件前进。比如
n-1、INT(n/10)、去掉第一个元素后的数组。 - 终止条件:明确写出何时直接返回,不再调用自己。比如
IF(n < 10, ...)。 - 边界覆盖:思考空值、负数、零、单元素这些边界情况。
只要有一个要素缺失,公式测试时可能偶然通过,一旦数据变化就崩溃。
8.3 命名规范与注释
名称管理器里的名称建议统一命名规则:
- 递归函数:
FIB_REC、NUM_TO_STR、TREE_EXPAND - 普通自定义函数:
GET_STATUS、CALC_TAX
名称尽量语义化,不要用F1、F2这种编号。不过,名称管理器不支持像代码那样的注释,建议把“函数用途”“参数含义”“终止条件说明”写在一个单独的说明单元格中,或者放到工作簿的“使用说明”工作表里,方便后续维护。
8.4 性能与全列引用
REDUCE和递归公式都应当避免引用整列,例如A:A或B:B。整列引用会让计算引擎处理 1048576 行潜在数据,即使大部分为空,也会产生明显的计算压力。更合理的做法是引用具体区域,比如A2:A2000,或者用动态数组区域。
如果公式会被大量单元格复制使用,建议统一改用LET把中间结果缓存起来。比如:
=LET(arr, A2:A2000, REDUCE("", arr, LAMBDA(acc, v, ...)))这样至少能让公式结构更清晰,也避免在多个位置重复计算同一个数组。
8.5 发布给同事前的小测试
如果你要把包含REDUCE或递归公式的工作簿交给同事使用,建议先完成一组最小验证:
- 用 5 行以内的测试数据确认逻辑正确。
- 用真实数据量测试运行时间,超过几十秒就要考虑优化。
- 在另一台电脑或另一个表格软件版本上测试兼容性,尤其是 WPS 环境。
- 如果对方不熟悉新函数,在“使用说明”里写清函数用途和修改位置。
这套流程看起来简单,却能避免最常见的“我电脑上没问题,你电脑上全报错”的尴尬。
9. 总结与后续学习方向
回到标题里的问题:REDUCE和LAMBDA递归,谁是盟主?我的答案已经很清楚:在“日常循环”这个赛道上,REDUCE是实用盟主,因为它稳定、自带终止条件、心智负担低;在“复杂拆解”这个赛道上,LAMBDA递归才是真正的能力盟主,因为只有它能处理树形结构、无限嵌套,以及各种需要函数自己调用自己的问题。而LAMBDA本身,则是这两个能力的共同地基。
真正值得你记住的不是“谁更强”,而是三句话:
- 数组遍历、累加、拼接、去重,优先用
REDUCE。 - 问题呈现“一层套一层”的结构时,再考虑
LAMBDA递归。 - 递归必须写终止条件,循环深度超限时,先把递归改成
REDUCE状态表。
接下来可以继续深入的方向,包括VSTACK、HSTACK与REDUCE组合构造动态表,MAP与SCAN的差异,以及LET函数对公式性能的优化。这一集先把循环与递归的底层逻辑打牢,下一集再聊如何用REDUCE构建真正的动态数据表,那时你会发现,所谓的盟主之争,其实没那么重要。