I have a list with this type: [(a, [a])]
.
For example:
[("a",["x","y"]),("x",["a","y"]),("z",[]),("y",["a","x"])]
I would like to filter this list. The filtering should work like this:
- start at first item, traverse items from first tuple
- remove keys that are in the first tuple (so remove
"x"
,"y"
)
End result should become:
[("a",["x","y"]),("z",[])] -- the "x" and "y" are removed because they live in "a"
The idea is to get a list and then to apply Map.delete
from import qualified Data.Map as Map
on that list. However, I'm stuck on the things when Maybe
is introduced. This is my code:
import System.IO
import Data.Maybe as Maybe
import qualified Data.Map as Map
list = [("a",["x","y"]),("x",["a","y"]),("z",[]),("y",["a","x"])]
main :: IO ()
main = do
let myMap = Map.fromList list
let myList = funcA list myMap
print myList
funcA (x:xs) myMap
| f == Nothing = Nothing
-- | otherwise = f
-- | otherwise = funcC f myMap
| otherwise = Maybe.maybeToList f
where a = fst x
f = funcB a myMap
funcB key myMap = Map.lookup key myMap
funcC portion myMap = portion
Can you help me out?
-------------- edit
After answering the code will look like this:
import System.IO
import Data.Maybe as Maybe
import qualified Data.Map as Map
list = [("a",["x","y"]),("x",["a","y"]),("z",[]),("y",["a","x"])]
main :: IO ()
main = do
let myList = removeKeys list
print myList
removeKeys :: Eq a => [(a, [a])] -> [(a, [a])]
removeKeys [] = []
removeKeys (kv@(_, vs): kvs) = kv : removeKeys (filter ((`notElem` vs). fst) kvs)
CodePudding user response:
You can make a recursive function that filters the rest of the list with the items in the second item of the 2-tuples, so:
removeKeys :: Eq a => [(a, [a])] -> [(a, [a])]
removeKeys [] = []
removeKeys (kv@(_, vs): kvs) = kv : removeKeys (filter ((`notElem` vs). fst) kvs)
The items in the values that are in the key-value pairs of removed items will not be considered. So if "x"
for example had ("x", ["a", "y", "z"])
, it will not remove "z"
, since it was in an item that was already removed.