[英]Finding ones in an array with J
我会用简单的英语解释我的问题,然后展示我在J.的尝试。
将1和0的列表的1的索引求和,并查看它们是否等于另一个数字。 例如,给定1 0 1 1 0,索引是0,2和3,并且它们的总和是5.因此我可以测试它是否可以算出另一个数字(在这种情况下,显然只有5)。
这是我的J:
indexsumtest =: =+/I.
v =: 1 0 1 1 0
5 indexsumtest v
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
什么? 这里我假设indexsumtest是一个二元动词,也许我需要明确地输入x和y?
indexsumtest =: x =+/I. y
5 indexsumtest v
|value error: x
| 5 indexsumtest v
不。 这让事情变得更糟。
所以我从头开始:
I. v
0 2 3
正确!
+/I. v
5
再次纠正。
5 =+/I. v
1
1意味着真实。 所以我做对了。
为什么我不能将这三个操作压缩成单个动词?
它是一个偶尔咬人的结果,因为它
5 =+/I. v
实际上我有一个作用于v,然后结果被+ /作用,然后使用=比较对照结果进行测试。 所以当我们定义时
indexsumtest =: =+/I.
我们得到
5 indexsumtest v
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
因为indexsumtest已被定义为默认动词,它将其参数作为MPelletier建议的fork处理。 换句话说,你实际上没有= + / I。 代替indexsumtest你得到(= + / I。)这是一个3动词叉,其中第一个和第三个动词同时接受两个参数,每个动词的结果被发送到中心的+ /。
MPelletier还建议你做一个你想要的默契形式
[ = [: +/ [: I. ]
如果你将你的定义更改为13,它将工作并实际由J创建
indexsumtest =: 13 : 'x =+/I. y'
indexsumtest
[ = [: +/ [: I. ]
是的,如果您使用13:连接来定义,那么J实际上将为您进行大多数默认转换。 很酷,嗯? 唯一的问题是它不会在这个自动生成中使用钩子,这可以简化代码。 一个钩子是一个双动词组合,它在右边的参数上有正确的动词作用,结果被用作左动词的右参数,它使用二元情形中的左参数(或monadic情形中的原始右参数) 。
当x和y是左右参数时,u和v是第一个和第二个动词
x ( uv) y
变为xu (vy)
或者在一元情况下
( uv) y
成为yu (vy)
如果你还在我身边(对你有好处!)这意味着如果我们将你设置为=和v到+ / @我,我们可以使用一个钩来简化默认。 (@是一个连接+ /和I的连接,并使它们作为一个动词起作用)。 最后
indexsumtacit =: = +/@I.
5 indexsumtacit v
1
正如J开始时的心态,当你理解它所遵循的规则然后开始让它们进行你的出价时,它真的很整洁。 希望这可以帮助。
考虑经典的平均函数:
mean =: +/%#
mean i.6
像这样的3部分声明以这种方式运行:
#
对y
执行 +/
是针对y
执行的 %
在各自的位置与+/
和#
的结果进行二元对比 原理与你的二元函数相同:
I.
针对x
和y
执行 =
对x
和y
执行 +/
在各自的位置对=
和I.
的结果执行 所以,做
indexsumtest =: =+/I.
5 indexsumtest 1 0 1 1 0
相当于
(5 = 1 0 1 1 0) +/ (5 I. 1 0 1 1 0)
远非你想要的。
简单的技巧是明确定义二元函数:
indexsumtest =: 4 : 'x =+/I. y'
J的默认定义也表明了这一点:
[ = [: +/ [: I. ]
这对我来说有点重。
这是关于J如何解析表达式的全部内容。 当J看到一个动词时,它隐含地在它周围添加一个括号。 所以5 indexsumtest v
是5 (=+/I.) v
; 而5 =+/I. v
5 =+/I. v
实际上是5 =+/ (I. v)
。 这两个与上面的答案不同。
我发现通过阅读Learning J的附录1来理解J如何评估表达式是非常有帮助的。 对于任何J教程,这应该是整章而不是附录。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.