从Haskell中的嵌套列表中删除项列表

时间:2011-02-07 15:38:10

标签: haskell nested-lists

想象一下如下的嵌套列表。

["A","ABBA","ABABA"]

我想创建一个从该列表中删除单例元素的函数(在本例中为“A”),删除包含该单例元素的任何列表。

那样:

removeElems ["A","ABBA","CCC"] -> ["CCC"]

以下是我尝试解决此问题的方法:

badElements nested = concat $ filter (\c -> length c == 1) nested

removeElements nested = [c | c <- nested, u <- badElements nested, not $ any (==u) c]

这会产生奇怪的结果,其中多个生成器'循环'嵌套列表,如下所示:

["A","ABBA","C","BCCB"] --> ["A","A","ABBA","ABBA","C","C","BCCB","BCCB"]--> ["A","ABBA","C","BCCB"]

另一个例子:

[[1],[1,2,3,4],[2],[5,6,7,8]] --> [5,6,7,8]

3 个答案:

答案 0 :(得分:2)

这是一个未经测试的尝试:

removeElements ls = filter (null . intersect singletons) ls
                    where singletons = mapMaybe singleElem ls
                          singleElem [x] = Just x
                          singleElem _ = Nothing

答案 1 :(得分:2)

由于您只想为每个列表元素生成零个或一个输出,因此您不希望迭代badElements的列表推导。相反,您希望过滤迭代badElements的谓词。

什么谓词?好吧,如果列表不包含坏元素,则列表很好。也就是说,它的所有元素都不错。

removeElements nested = filter (all (`notElem` badElements nested)) nested

答案 2 :(得分:1)

另一次尝试:

badElements :: [[a]] -> [a]
badElements = concat . filter (\x -> 1 == length x)

removeBadElements :: (Eq a) => [[a]] -> [[a]]
removeBadElements xs = filter (\x -> not $ any ((flip elem) x) (badElements xs) ) xs

badElements将返回一个列表,其中包含其参数的所有单例元素(类似于badElements应该执行的操作:

badElements [[1],[1,2,3,4],[2],[5,6,7,8]]
[1,2]
然后,

removeBadElements删除包含badElements元素的所有元素。