想象一下如下的嵌套列表。
["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]
答案 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
元素的所有元素。