删除列表中的直接重复项

时间:2016-04-20 14:18:12

标签: haskell

所以我应该从列表中删除彼此相邻的直接重复项。例如1,3,3,3,2,4,4,2,4] = [1,3,2,4,2,4]或[63,65,65,64,65,63,65, 65,64,64,65] = [63,65,64,65,63,65,64,65]。我的代码只删除所有重复项。我认为我的问题是我与elem比较,我需要一个只与下一个元素进行比较的函数。

module Blueprint where
import Prelude

compress :: [Int] -> [Int]
compress [] = []
compress (x:xs)   | x `elem` xs   = compress xs
                  | otherwise     = x : compress xs

3 个答案:

答案 0 :(得分:6)

现在您正在检查x是否在函数的其余部分中有重复。您实际上想要检查下一个元素是否重复。您可以通过查看列表的前两个元素而不仅仅是第一个元素来完成此操作。

compress :: [Int] -> [Int]
compress [] = []
compress [x] = [x]
compress (x:x2:xs) | x == x2   = compress (x2:xs)
                   | otherwise = x : compress (x2:xs)

答案 1 :(得分:4)

group函数找到相邻的相等值并将它们组合在一起。所以你的功能可以实现为

compress = map head . group

首先,使用head可能会很危险;但是,group的承诺是它返回的每个元素都是非空列表。

答案 2 :(得分:1)

我最近从这种小折叠技术中获得了很多好处:

smash :: Eq a => [a] -> [a]
smash xs = foldr go (`seq` []) xs Nothing
  where
    go x r (Just prev)
      | x == prev = r (Just x)
    go x r _ = x : r (Just x)