2012-08-13 82 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只查看阵列中的每个元素一次,并且您没有关于以前元素的信息。