2011-10-07 75 views
1

哈斯克尔大师。小心向我展示一些更多的haskellian方法来执行这个任务,这并不受我对haskell和FP的有限知识的限制。分组重复

groupDups [] = [] 
groupDups [email protected](x:xs) = groupDups' x list 
    where groupDups' _ [] = [] 
     groupDups' x list = let (m,r) = partition (x ==) list 
          in m : groupDups r 

> groupDups [1,2,3,4,1,2,3,4,4,3,2,1,4,3,2,1] 
[[1,1,1,1],[2,2,2,2],[3,3,3,3],[4,4,4,4]] 

回答

4

你可以sort列表,然后group它:

> import Data.List 
> (group . sort) [1,2,3,4,1,2,3,4,4,3,2,1,4,3,2,1] 
[[1,1,1,1],[2,2,2,2],[3,3,3,3],[4,4,4,4]] 
+0

干杯,速度快得多,看起来像我在思考的事情再次。但是,现在我需要为我的自定义数据类型实现一个Ord实例。 – nipuL

+0

@nipuL,或者你可以使用'sortBy'而不是排序。那么你只需要'Eq'代表'group'。 –

+0

'sortBy'仍然需要一个函数,该函数返回给定两个键的'Ordering'。 – pat

1

如果你想避免在类型引入Ord约束您可以使用此:

import Data.List 

groupDups []  = [] 
groupDups (x:xs) = (x : group) : groupDups xs' where 
    (group,xs') = partition (==x) xs 

这相应地比(group . sort)慢,并且组按原始列表中的第一次出现排序:

*Main> groupDups [1,3,2,3,4,1,2,3,4,4,3,2,1,4,3,2,1] 
[[1,1,1,1],[3,3,3,3,3],[2,2,2,2],[4,4,4,4]] 

您可以通过制作一个帮助函数累积到参数列表中,稍微提高复杂度,询问您是否对细节感兴趣。

0

这样做很奇怪。

groupDups ls = 
    map (\(h:­t) -> t) $ foldl­ (\s e -> map (\(h:­t) -> if h == e then (e:h:­t) else (h:t)­) s) (nub [[x] | x <- ls])­ ls 
0

此功能只需要Eq

groupDups xs = foldl insert [] xs 
    where insert [] x = [[x]] 
     insert ([email protected](y:_):yss) x | x == y = (x:ys):yss 
           | otherwise = ys:(insert yss x)