[英]How to filter a list in J?
我目前正在學習迷人的J編程語言,但有一點我無法弄清楚如何過濾列表。
假設我有任意列表3 2 2 7 7 2 9
並且我想刪除2s但保留其他所有內容,即我的結果將是3 7 7 9
。 我怎么做到這一點?
2 (~: # ]) 3 2 2 7 7 2 9
3 7 7 9
我有你的答案,但在你熟悉一些細節之前。 開始了。
J中有兩種類型的動詞 : monad和dyads 。 前者只接受一個參數,后者接受兩個參數。
例如,將唯一參數傳遞給monadic動詞#
,稱為tally ,計算列表中元素的數量:
# 3 2 2 7 7 2 9
7
接受兩個參數(左和右)的動詞#
被稱為副本 ,它是二元的 ,用於從左側列表中的相應元素指定的次數復制右側列表中的元素(可能有一個列表中的元素也):
0 0 0 3 0 0 0 # 3 2 2 7 7 2 9
7 7 7
在J中有一個fork概念,它是一系列3個動詞,適用於他們的論證,可以是二元或一元的。
這是我在第一個片段中使用的一種分支圖:
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
時,這些值為真。 這是根據圖表的F
應用程序。
下一個應用是H
:
2 ] 3 2 2 7 7 2 9
3 2 2 7 7 2 9
]
( identity )可以是monad或dyad ,但它總是返回傳遞給動詞的正確參數(有一個相反的動詞, [
返回..是的,左邊的參數!:)
到現在為止還挺好。 應用程序后的F
和H
相應地返回這些值:
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
秒過濾了列表。
這兩個文件中描述了稍微不同的叉子 , 鈎子和其他原始物(包括上面提到的):
其他有用的信息來源是Jsoftware網站 及其wiki以及互聯網中的一些郵件列表存檔。
只是為了確定它是清楚的,直接的方式 - 回答原始問題 - 是這樣的:
3 2 2 7 7 2 9 -. 2
這回來了
3 7 7 9
更精細的方法 - 生成布爾值並使用它來壓縮向量 - 更加簡潔。
要在非常長的帖子中回答另一個問題,要返回第一個元素及其發生的次數,只需:
({. , {. +/ .= ]) 1 4 1 4 2 1 3 5
1 3
這是一個使用“{。”的分支。 得到第一項,“{。+ /。=]”加起來第一項等於每個元素的次數,“,”作為連接這兩部分的中間動詞。
也:
2 ( -. ~ ]) 3 2 2 7 7 2 9
3 7 7 9
有一百萬種方法可以做到這一點 - 模糊地說,讓我困擾的是,這些事情並沒有嚴格從右到左進行評估,我是一個老的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)。
該程序回答了這樣一個問題,“對於所有可能的8位數字,從符號1到5,重復,有多少可以被4整除?”
我知道你只需要確定前25個中有多少可被4整除並相乘,但程序或多或少會立即運行。 有一次,我有一個更復雜的程序版本,它生成了基數為5的數字,以便各個數字在0到4之間,為這樣生成的數字加1,然后將它們放入基數10。這就像是1+(8$5)#:i.5^8
+ / 0 = 4 |,(8 $ 10)#。 > {; / 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元素,並以某種方式記錄這些數字,最終的想法是有另一個階段,我將向量的逆應用於原始列表,並且然后使用$:來獲取相同動詞的遞歸應用。 有點像快速排序的例子,我認為我有點理解,但我想我沒有。
但我甚至無法接近。 我會將此問題作為一個單獨的問題,以便人們獲得適當的回答。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.