2012-12-07 69 views
3

假設有一個列表的erlang列表:Erlang列表與元組比較

請注意列表的大小是固定的。在這種情況下3

A = [[1,2,3],[4,5,6],[1,8,3],[1,9,3]] 

我試圖寫功能,將放棄所有這些都是形式[1,_,3]的元素。 所以我的預期輸出的形式如下:[[4,5,6]]

我可以考慮的一個解決方案是列表:dropwhile()函數可以使用。

我在構造謂詞函數時遇到了問題。將每個元素轉換爲元組並將其進行比較更容易嗎?如果是這樣,沒有適當的方式可以省略中間元素。

你能幫我解決問題嗎?任何其他有效的方法也將受到高度讚賞。

在此先感謝!

編輯: 問題Extenstion:

假設列出兩個二郎列表:

A = [[1,2,3],[2,3,4],[4,5,6 ]

B = [[1,4,3],[4,7,6],[7,8,9],[4,9,7],]

輸出F( A,B)= [[7,8,9],[4,9,7]]

F被定義爲一個函數,它從列表B中刪除所有t他是與第一和第三位置中的列表A中的任何一個元素相匹配的元素。

在這種情況下,從列表中刪除列表B中匹配[1,_,3]或[2,_,4]或[4,_,6]的所有元素以給出結果列表。

我很努力寫F.

+0

什麼你的謂詞函數看起來像迄今爲止?我想你會發現它對於元組或列表來說非常相似。 – legoscia

+0

到目前爲止,我的最大努力一直是, 列表:過濾器(fun(X) - > {1,_,3} == erlang:list_to_tuple(X)end,A)。 但我得到一個_ unbound變量錯誤。等於(=)的單個變量如果爲false,則不會返回true或false。 – Maverickgugu

回答

3

dropWhile只能返回列表的前綴,所以它不是去上班。改爲使用filter

+0

感謝您的提示。我終於明白了不同之處。 – Maverickgugu

12

您的篩選功能需要一些幫助:

lists:filter(fun([1, _, 3]) -> false; (_) -> true end, 
      [[1,2,3],[4,5,6],[1,8,3],[1,9,3]]). 

你需要在比賽中的函數頭,使這項工作。


作爲具有多個過濾器,可以使用地圖玩意兒(未測試)的一個:

composed_filter(Tests, Input) -> 
    lists:filter(fun(X) -> lists:all([F(X) || F <- Tests]) end, 
       Input). 

對於使用多個過濾器,可以這樣做:

filter(fun([1,_,3]) -> true; 
      ([5,_,7]) -> true; 
      ([9,_,13]) -> true; 
      (_) -> false end, Input) 
% or 
composed_filter([fun([1,_,3]) -> true; (_) -> false end, 
       fun([5,_,7]) -> true; (_) -> false end, 
       fun([9,_,13]) -> true; (_) -> false end], 
       Input) 

雖然除非需要可編程動態組合性,您可能應該只使用 首先。另一種方法是使用函數運行組合,而不是使用專門的composer_filter。這是Haskell人羣會喜歡的更加組合式的方法。請注意,上述功能稍有不同。第一個語義是orelse,而後者有andalso語義。在第一種情況下,如果一個或多個模式匹配,則得到元素,而在後一種情況下,如果全部模式/樂譜匹配,則只會得到結果。您可以使用lists:any/2獲得composed_any_filter

+0

是否有可能在同一個過濾函數中有兩個謂詞?在這種情況下,函數標題將是一個混亂的權利? 我能想到的唯一方法是讓列表通過兩個如上定義的順序過濾器。但我想這不會使它具有任何新的額外謂詞的規模...... – Maverickgugu

+1

添加到一個解決方案的答案。還有更多這樣的解決方案,包括兩次走單子。這可能會產生開銷,儘管取決於您試圖走的列表。 –

+0

這是一個優雅的解決方案。但是,我們將如何獲得一個函數列表。假設對於問題中定義的相同問題,如果我們不僅要比較[1,_,3] ..還要比較[1,_,5],[7,_9]等等。那時把它們全部寫入一個過濾器是可取的? – Maverickgugu

1

我設法想出了擴展問題的解決方案:

鑑於A和B的問題:

F(A,B) -> 
    lists:filter(fun(X) -> predicate(X,B) end, A). 

predicate(X, B) -> 
    Xr = lists:delete(lists:nth(2,X),X), 
    Br = lists:map(lists:delete(lists:nth(2,Y),Y),B), 
    lists:member(Xr, Br). 

此列出庫是太酷了.. :)