2012-08-13 117 views
1

我有[a]可以轉換爲[b]。每個a是不同的,但每個b可能不是。我想過濾我的[a],條件是過濾的[a]轉換爲[b]時不包含重複項。如何過濾此列表?

有人可以幫助我實現這一目標嗎?

編輯

以服務爲輔助,我會提供一個例子。

as = [1..10] 
conv = even 
bs = map even as 
-- bs = [False,True,False,True,False,True,False,True,False,True] 
-- filter <cond> as -- [1,2] 

回答

9

假定f是將從ab功能。然後,您可以繼續在三個步驟:

  1. 您配對名單,其圖像的每個元素f下:map (id &&& f);
  2. 您刪除了第二個元素已經出現在現在獲得的列表中的每一對:nubBy (on (==) snd);
  3. 您刪除每對中的第二個組件:map fst

因此:

import Control.Arrow ((&&&)) 
import Data.Function (on) 
import Data.List (nubBy) 

filterOn :: Eq b => (a -> b) -> [a] -> [a] 
filterOn f = map fst . nubBy ((==) `on` snd) . map (id &&& f) 

例如:

> filterOn even [1 .. 10] 
[1,2] 
+0

輝煌,這個作品! – 2012-08-13 10:30:36

+0

a [Schwartzian transform](http://en.wikipedia.org/wiki/Schwartzian_transform)! – 2012-08-13 19:36:40

1

這是不可能用(filter cond) [1..10]得到[1,2]具有cond :: a -> Bool功能和僅filter,即做到這一點。

問題是,filter只查看陣列中的每個元素一次,並且您沒有關於以前元素的信息。