假设我有一个动词 v
,例如,定义为 v=.>:@*:
, 我想申请 v
到某个初始值 n
次,并将所有中间结果存储在一个向量中,如下所示 n=4
和初始值 2
2 5 26 677 458330
我不确定如何在应用动词时“扩展”向量,尽管我知道可能可以使用 ^:
做申请n
次。
请帮忙。
请您参考如下方法:
J 具有用于此操作和相关操作的内置运算符:^:
(读“权力”)。您正在寻找的特定种类的权力是当它的右手参数是一个盒装数字(或数字)时:
v^:(<n) initial_value
如/:
>:@*:^:(<1+4) 2
2 5 26 677 458330
要使其成为可重用的动词(对
n
和初始值进行抽象):
vv =: >:@*:@]^:(<@>:@[)
4 vv 2
2 5 26 677 458330
要使其成为可重用的副词(抽象于
n
、初始值和
v
):
V =: (@]) (^:(<@>:@[))
4 >:@*: V 2
2 5 26 677 458330
请注意
^:
还有其他口味。例如,如果它的右侧参数是一个未装箱的数字(或多个数字),它只会应用该函数 N 次并生成最终值,而不是构建一个中间值向量。
或者,如果它的右手边的参数是无限的,它将把函数应用到它的不动点。或者,将这两个观察结果结合起来,如果其右侧参数是装箱且无限的,则它将函数应用于其不动点,沿途构建一个中间值向量。还有很多其他巧妙的技巧。
PS:编写函数
>:
与功能
*:
使用
@
如
>:@*:
将正确产生输入平方加一。
但是,由于
@
被定义为像一条流水线一样,传递
*:
的每个输出至
>:
单独地,后一个动词(增量)将被调用
#y
次。使用
@:
可以更有效地获得相同的结果("atop") 代替
@
(“在”)。
作为组合运算符,
@:
与其说是流水线,不如说更像是料斗:它在等待
*:
完成处理,将所有结果收集在一起,并将它们传递给
>:
一气呵成。
鉴于 J 的面向数组的性质,经验法则是“从大处着眼”。也就是让每个基元看到尽可能多的数据,让解释器管理细节。在您学习 J 时,可能值得采用“使用 @: 而不是 @”作为一揽子规则,直到您掌握细微差别为止。