简体   繁体   中英

Haskell: Output list of tuples as string output

I'm trying to get this list of tuples:

[(2,"a"), (1,"a"), (1,"b"), (1,"c"), (2,"dd")]

into this string output

a 1,2

b 1

c 1

dd 2

I assume I need to use the unzip and unlines functions. But I also saw some solutions using the show function which makes the integers strings. Any ideas?

If you have this list:

pairs = [ ("a", [1,2]), ("b", [1]), ("c", [1]), ("dd", [2]) ]

then you can get the desired output with:

putStrLn $ unlines [ x ++ " " ++ unwords (map show ys) | (x, ys) <- pairs ]

but you have to figure out how to get the pairs list first.

Break the problem down into steps. What you really want to do first is aggregate all the tuples that have the same string in the second position, so you'll have a function like

aggregate :: [(Int, String)] -> [([Int], String)]

So for your input list you would get the output

[([1, 2], "a"), ([1], "b"), ([1], "c"), ([2], "dd")]

Your hints are

aggregate items = someFunc (map (\(num, str) -> ([num], str)) items)

And take a look at foldr . Before you ask a follow up question about foldr , there are probably hundreds of stackoverflow answers showing how to use it already, take some time to figure it out or it'll get closed immediately as a duplicate.

Then you need a function to convert a single tuple of this form into a single String for outputting:

prettyPrint :: ([Int], String) -> String
prettyPrint (nums, str) = str ++ " " ++ joinWithComma (map show nums)

Where you'll have to implement joinWithComma yourself. Then you need to calculate this and print it for each item in your aggregated list, mapM_ and putStrLn would be preferred, so your main might look like

main :: IO ()
main = do
    let inputList = [(2,"a"), (1,"a"), (1,"b"), (1,"c"), (2,"dd")]
    mapM_ (putStrLn . prettyPrint) (aggregate inputList)

Work step by step. You could start with the groupBy function:

groupBy (\x y-> (snd x)==(snd y)) [(2,"a"), (1,"a"), (1,"b"), (1,"c"), (2,"dd")]

gives you

[[(2,"a"),(1,"a")],[(1,"b")],[(1,"c")],[(2,"dd")]]

The next step would be "totalling" the inner lists, map and foldL (and depending on your requirements maybe sortBy ) should be helpful. If you have this, constructing the output is trivial (using show , as you already mentioned).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM