我有问题。我有一项无法自行解决的任务。这是交易:
extPair :: Eq a => [(a,b)] -> [(a,[b])]
如果我想用以下方式打电话:
extPair [(3,"pear"),(3,"fog"),(4,"dog"),(4,"x"),(3,"y")]
应该给出以下结果:
[(3, ["pear", "fog"]), (4, ["dog", "x"]), (3, ["y"])] :: [(Integer, [[Char]])]
我现在所知道的是:
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])]
这适用于该示例,但它不适用于以下内容,而且我不知道如何制作它,所以我请求您的帮助。我想添加尽可能多的对:
extPair [(3,"pear"),(3,"fog"),(3,"dark"),(3,"etc"), ... ,(4,"dog"),(4,"x"),(3,"y"),(3,"z")]
所以结果应该是:
[(3, ["pear", "fog", "dark", "etc", "...", "...", ...]), (4, ["dog", "x"]), (3, ["y", "z"])] :: [(Integer, [[Char]])]
答案 0 :(得分:3)
使用foldr
函数的另一种解决方案:
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
答案 1 :(得分:1)
您可以先使用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")]]
从那里开始,使用map f
获取合适的f
。
如果您想编写自己的代码,请考虑递归:
extPair ((n,s):xs) = ???
where ys = extPair xs
此处的逻辑如下:如果ys
以(n,zs)
开头,则将s
添加到zs
,否则将(n,[s])
添加到ys
}。