Populating a list of tuples in a semantic way

前端 未结 1 932
萌比男神i
萌比男神i 2021-01-23 09:10

I\'m working on a piece of code where I have to process lists of tuples where both the order and names of the \"keys\" (fsts of the tuples) match a certain template

1条回答
  •  时光取名叫无心
    2021-01-23 09:45

    You essentially want to map a function to your list of strings (which you call "template"), i.e. the function that

    • takes a string xs,
    • returns
      • (xs, Just n) if an integer n is associated to xs in your "list to validate",
      • (xs, Nothing) otherwise.

    Here is one possible approach:

    import Data.List     ( lookup )
    import Control.Monad ( join )
    
    consolidate :: [String] -> [(String, Maybe Int)] -> [(String, Maybe Int)]
    consolidate temp l = map (\xs -> (xs, join $ lookup xs l)) temp
    

    However, you will get faster lookup if you build a Map holding the key-value pairs of your association list (the "list to validate"):

    import qualified Data.Map as M
    import Data.Maybe (maybe)
    
    consolidate :: [String] -> [(String, Maybe Int)] -> [(String, Maybe Int)]
    consolidate temp l = map (\cs -> (cs, M.lookup cs $ fromList' l)) temp
    
    fromList' :: Ord a => [(a, Maybe b)] -> M.Map a b
    fromList' xs = foldr insertJust M.empty xs
    
    insertJust :: Ord a => (a, Maybe b) -> M.Map a b -> M.Map a b
    insertJust (xs, maybeVal) mp = maybe mp (\n -> M.insert xs n mp) maybeVal
    

    In GHCi:

    λ> let myTemplate = ["hello", "world", "this", "is", "a", "test"]
    λ> let myList = [("hello", Just 1), ("world", Just 2), ("test", Just 3)]
    λ> consolidate myTemplate myList 
    [("hello",Just 1),("world",Just 2),("this",Nothing),("is",Nothing),("a",Nothing),("test",Just 3)]
    

    0 讨论(0)
提交回复
热议问题