Reputation: 81
I have a problem. I have a task that can't solve on my own. Here is the deal:
extPair :: Eq a => [(a,b)] -> [(a,[b])]
If I want to call this with:
extPair [(3,"pear"),(3,"fog"),(4,"dog"),(4,"x"),(3,"y")]
Should give the following result:
[(3, ["pear", "fog"]), (4, ["dog", "x"]), (3, ["y"])] :: [(Integer, [[Char]])]
All I know now is:
extPair [] = []
extPair (x:xs)
| length (x:xs) >= 2 && fst x == fst (head xs) = [(fst x, [snd x, snd (head xs)])] ++ extPair (drop 1 xs)
| otherwise = [(fst x, [snd x])]
This works fine for the example, but it doesn't work on the following, and I don't know how to make it, so I ask Your help. I would like to add as many pairs as I want like:
extPair [(3,"pear"),(3,"fog"),(3,"dark"),(3,"etc"), ... ,(4,"dog"),(4,"x"),(3,"y"),(3,"z")]
So the result should be:
[(3, ["pear", "fog", "dark", "etc", "...", "...", ...]), (4, ["dog", "x"]), (3, ["y", "z"])] :: [(Integer, [[Char]])]
Upvotes: 0
Views: 526
Reputation: 1568
Yet another solution using the foldr
function:
extPair :: Eq a => [(a,b)] -> [(a,[b])]
extPair = foldr f []
where
f (key, elem) [] = [(key, [elem])]
f (key1, elem) l@((key2, elems):xs)
| key1 == key2 = (key2,elem:elems):xs
| otherwise = (key1,[elem]):l
Upvotes: 3
Reputation: 116174
You can start by pre-processing the list with groupBy
:
> import Data.List
> import Data.Function
> groupBy ((==) `on` fst) [(3,"pear"),(3,"fog"),(4,"dog"),(4,"x"),(3,"y")]
[[(3,"pear"),(3,"fog")],[(4,"dog"),(4,"x")],[(3,"y")]]
From there, use map f
for a suitable f
.
If you instead want to write your own code, consider recursion:
extPair ((n,s):xs) = ???
where ys = extPair xs
the logic here would something like: if ys
starts with (n,zs)
, then prepend s
to zs
, otherwise prepend (n,[s])
to ys
.
Upvotes: 1