1

想象一个嵌套列表如下。

["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]
4

3 回答 3

2

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

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

removeElements nested = filter (all (`notElem` badElements nested)) nested
于 2011-02-07T16:34:02.383 回答
2

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

removeElements ls = filter (null . intersect singletons) ls
                    where singletons = mapMaybe singleElem ls
                          singleElem [x] = Just x
                          singleElem _ = Nothing
于 2011-02-07T16:11:28.040 回答
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

于 2011-02-07T16:29:40.100 回答