Reputation: 2085
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?
Upvotes: 0
Views: 2779
Reputation: 54584
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).
Upvotes: 0
Reputation: 54058
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)
Upvotes: 2
Reputation: 52039
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.
Upvotes: 2