如何过滤J中的列表?

时间:2010-05-19 10:55:36

标签: j tacit-programming

我目前正在学习迷人的J编程语言,但有一点我无法弄清楚如何过滤列表。

假设我有任意列表3 2 2 7 7 2 9,我想删除2,但保持其他所有内容不变,即我的结果为3 7 7 9。我该怎么做呢?

4 个答案:

答案 0 :(得分:31)

简答

   2 (~: # ]) 3 2 2 7 7 2 9
3 7 7 9


答案很长

我有答案,但在你熟悉一些细节之前。我们走了。

Monads,dyads

J中有两种类型的动词 monads dyads 。前者只接受一个参数,后者接受两个参数。

例如,将唯一参数传递给名为 tally monadic 动词#,计算列表中元素的数量:

   # 3 2 2 7 7 2 9
7

动词#接受两个参数(左和右),称为 copy ,它是二元,用于复制元素右列表由左侧列表中的相应元素指定的次数(列表中可能还有唯一的元素):

   0 0 0 3 0 0 0 # 3 2 2 7 7 2 9
7 7 7

J中有一个 fork 的概念,它是一系列3个动词,应用于它们的参数,可以是二元或一元的。

这是我在第一个片段中使用的一种 fork 的图表:

 x (F G H) y

      G
    /   \
   F     H
  / \   / \
 x   y x   y

它描述了动词应用于其参数的顺序。因此,这些应用程序发生:

   2 ~: 3 2 2 7 7 2 9
1 0 0 1 1 0 1

此示例中的~:(不等于)是二元,并产生一个布尔值列表,当参数不等于2时,这些值为true。根据图表,这是F应用程序。

下一个申请是H

   2 ] 3 2 2 7 7 2 9
3 2 2 7 7 2 9

] identity )可以是 monad dyad ,但它始终返回传递给a的正确参数动词(有一个相反的动词,[返回..是的,左边的参数!:)

到目前为止,这么好。应用程序后FH相应地返回这些值:

1 0 0 1 1 0 1
3 2 2 7 7 2 9

唯一要执行的步骤是G动词应用程序。

正如我前面提到的,动词#,它是二元(接受两个参数),允许我们从右边的参数复制项目的次数,分别是相应的左参数中的位置。因此:

   1 0 0 1 1 0 1 # 3 2 2 7 7 2 9
3 7 7 9

我们刚刚从2 s过滤了列表。

参考

这两个文件中描述了稍微不同的 fork hook 和其他原始文件(包括上述文章):

其他有用的信息来源是Jsoftware sitetheir wiki以及互联网中的一些邮件列表档案。

答案 1 :(得分:6)

为了确保清楚,回答原始问题的直接方式是:

   3 2 2 7 7 2 9 -. 2

返回

3 7 7 9

更精细的方法 - 生成布尔值并使用它来压缩矢量 - 更加简洁。

要在非常长的帖子中回答另一个问题,要返回第一个元素及其发生的次数,只需这样:

      ({. , {. +/ .= ]) 1 4 1 4 2 1 3 5
1 3

这是一个使用“{。”的分叉。获得第一项,“{。+ /。=]”以将第一项等于每个元素的次数加起来,并将“,”作为连接这两部分的中间动词。

答案 2 :(得分:4)

另外:

   2 ( -. ~ ]) 3 2 2 7 7 2 9
3 7 7 9

答案 3 :(得分:1)

有一百万种方法可以做到这一点 - 模糊地说,让我困扰的是,这些事情并没有严格地从右到左评估,我是一个老的APL程序员,我认为即使他们这些东西也是合适的不是

如果我打算将某个程序放入一个程序中,我想提取一些数字并且数字是常数,我会做以下事情:

(#~ 2&~:)  1 3 2 4 2 5
1 3 4 5 

我认为这是一种钩子。表达式的右半部分生成的真值向量不是2,然后左边的octothorpe交换了参数,因此真值向量是要复制的左参数,向量是正确的参数。我不确定钩子比带有参数副本的fork更快还是更慢。

  +/3<+/"1(=2&{"1)/:~S:_1{;/5 6$1+i.6

156

上述程序回答了一个问题,“对于Yatzee骰子的所有可能组合,一个卷中有多少个有4个或5个匹配数字?”它生成所有排列,在框中,单独对每个框进行排序,将它们作为副作用取消装箱,并提取第2列,将框与它们自己的第2列进行比较,在我曾经设法编写的唯一成功的fork或hook中。理论上说,如果列表中出现的数字为5次,3次或更多次,如果对列表进行排序,则中间数字将是出现频率最高的数字。我尝试过其他一些钩子和/或叉子,每一个都失败了,因为有些东西我没有得到。无论如何,真值表被简化为一个向量,现在我们确切地知道每组5个骰子与中位数相匹配的次数。最后,将该数字与3进行比较,并计算成功比较的数量(大于3,即4或5)。

该程序回答了这样的问题,“对于从符号1到5中重复出现的所有可能的8位数字,有多少可以被4整除?”

我知道你只需要确定前25个中有多少可以被4整除并且相乘,但程序会或多或少立即运行。有一次,我有一个更复杂的程序版本,它生成了基数为5的数字,以便各个数字在0到4之间,为这样生成的数字加1,然后将它们放入基数10。这就像是1+(8$5)#:i.5^8   + / 0 = 4 |,(8 $ 10)#。 &gt; {; / 8 5 $ 1 + i.5 78125    只要我有动词列车和选择,我就没有问题。当我开始不得不在动词中重复我的论点,以便我被迫使用叉子和钩子时,我开始迷路。

例如,这是我无法开展的工作。

((1&{~+/)*./\(=1&{))1 1 1 3 2 4 1

我总是得到索引错误。

要点是输出两个数字,一个与列表中的第一个数字相同,第二个数字与重复该数字的次数相同。

所以这很有效:

*./\(=1&{)1 1 1 3 2 4 1
1 1 1 0 0 0 0

我将第一个数字与列表的其余部分进行比较。然后我插入一个和压缩 - 这给了我一个1,只要我有一个完整的1的字符串,一旦它打破并失败并且零出现。

我认为我可以添加另一组parens,再次从列表中获取lead元素,并以某种方式记录这些数字,最终的想法是有另一个阶段,我将矢量的逆应用于原始列表,然后使用$:来获取相同动词的递归应用程序。有点像快速排序的例子,我认为我有点理解,但我想我没有。

但我甚至无法接近。我会将此问题作为一个单独的问题,以便人们获得适当的回答。

相关问题