开发者

Removing a list of items from a nested list in Haskell

开发者 https://www.devze.com 2023-02-09 15:48 出处:网络
Imagine a nested list as below. [\"A\",\"ABBA\",\"ABABA\"] I would like to create a function which 开发者_运维问答removes singleton elements from this list (in this example, \"A\"), and removes any

Imagine a nested list as below.

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

I would like to create a function which 开发者_运维问答removes singleton elements from this list (in this example, "A"), and removes any lists containing that singleton element.

So that:

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

Below is my attempt at solving this problem:

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

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

This produces strange results where the multiple generators 'cycle' the nested list, such as below:

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

Another example:

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


Since you only want to produce zero or one outputs for each list element, you don't want a list comprehension that iterates over badElements. Instead, you want to filter on a predicate that iterates over badElements.

What predicate? Well, a list is good if it doesn't contain a bad element. That is, all of its elements are not bad.

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


Here's an untested attempt at it:

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


Another attempt:

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 will return a list with all the singleton elements of its parameter (similar to what your badElements is supposed to do:

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

removeBadElements, then, removes all the elements that contain an element of badElements.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号