我尝试在 Google Sheets 上采用函数式编程风格,并得到了相当令人满意的结果,例如函子、递归函数和柯里化函数。然而,我被管道功能困住了。
使用其他现代编程语言实现管道函数非常容易,因为它们允许我们将函数包装在数组中,该数组可以解开并返回我们的函数以及原始函数。
例如,使用 JavaScript,我们有
function pipe(){
return input => [...arguments].reduce((result, func)=>func(result), input)
}
这样我们就可以这样做:
pipe(plusThree, multiplyFour, minusSeven)(2)
但是,在 Google Sheets 上,创建数组的唯一方法似乎是将项目放入“虚拟”范围(一组单元格)中,无论我们是使用 MAKEARRAY 还是 {"func", "arr"}。不幸的是,一旦我们将函数放入单元格中,它就会立即执行并返回错误。因此,我尝试的公式失败了
=LET(
plusOne, LAMBDA(num, num+1),
multTwo, LAMBDA(num, num*2),
pipe, LAMBDA(functions,
LAMBDA(input,
LET(
recursiveFunction,
LAMBDA(self, idx,
IF(
idx < COLUMNS(functions),
CHOOSECOLS(functions, idx)(self(self, idx+1)),
CHOOSECOLS(functions, idx)(input)
)
),
recursiveFunction(recursiveFunction, 1)))),
result, pipe({plusOne, multTwo})(5),
result
)
(很抱歉使用递归函数。如果我用 REDUCE 编写它会更容易阅读,我第一次尝试但失败了,遗憾的是。)
关键点是我没有任何其他方法来解包函数数组并获取其中解包的函数以及包装之前的函数!
Google Sheets 中的 LAMBDA 不允许我们在函数中拥有不确定数量的参数(这太令人沮丧了)。零参数也是不允许的。 (不过,我们可以使用无意义的占位符来模拟它。)因此,即使 CHOOSE 似乎是迭代参数的候选者,而不将其包装在(类似范围的)数组中,我们的管道函数也不能将其用作迭代函数的关键部分,因为争论。
所以,我真的很想知道这是否是一种在 Google Sheets 上模拟管道功能的方法。
我正在处理的电子表格记录在此处,供任何可能关注的人使用: https://docs.google.com/spreadsheets/d/1Z1_udcul2sNtzBtJbCeDlnMR2J4JymytfScKFyUtiw8/edit#gid=1987950802
非常感谢任何讨论或想法!
您可以模拟管道功能,如下*:
=LET(
PIPE,LAMBDA(Functions,Initial,
LET(plusOne,LAMBDA(n,n+1),
multTwo,LAMBDA(n,n*2),
fxNames,{"plusOne";"multTwo"},
CHOOSER_,LAMBDA(name,CHOOSE(XMATCH(name,fxNames),plusOne,multTwo)),
REDUCE(Initial,Functions,LAMBDA(prev,cur,CHOOSER_(cur)(prev))))),
PIPE({"plusOne","multTwo"},2)
)
REDUCE
函数和当前值数组(函数数组),并在 LAMBDA 参数中调用它们:
CHOOSER_(cur)(prev)
其中
CHOOSER_
是一个自定义函数,通过运行 XMATCH
选择感兴趣的函数,以选择 fxNames
中函数的索引,并运行 CHOOSE
选择实际函数。