2011-10-07 60 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)