Haskell 如何返回合并元组的列表?
目前我有一个元组列表[(1,[1]),(2,[1]),(3,[1]),(1,[2]),(3,[2]),(1,[3])。我想返回[(1,[1,2,3]),(2,[1]),(3,[1,2])的列表 我编写了一个合并两个元组的合并方法Haskell 如何返回合并元组的列表?,haskell,Haskell,目前我有一个元组列表[(1,[1]),(2,[1]),(3,[1]),(1,[2]),(3,[2]),(1,[3])。我想返回[(1,[1,2,3]),(2,[1]),(3,[1,2])的列表 我编写了一个合并两个元组的合并方法 merge :: Ord a => (a,[Int]) -> (a,[Int]) -> (a,[Int]) merge (x,y) (w,z) = (x, y ++ z ) 以及检查每个元组的第一个元素是否相等的方法 isEqual :: Ord a
merge :: Ord a => (a,[Int]) -> (a,[Int]) -> (a,[Int])
merge (x,y) (w,z) = (x, y ++ z )
以及检查每个元组的第一个元素是否相等的方法
isEqual :: Ord a => (a,[Int]) -> (a,[Int]) -> Bool
isEqual (x,y) (w,z)
| x == w = True
| otherwise = False
我很难想出一种方法来对每个元素运行isEqual和merge方法,尽管这样可以得到答案。你们推荐折叠法还是递归法?谢谢 一般来说,要有效地解决这类问题,需要将值存储在映射结构中,以便通过匹配的“键”轻松访问。这样,当您遇到
(1,[2])
时,您可以快速查阅地图,查看您已经有(1,[1])
,并将它们组合起来得到(1,[1,2])
。稍后,当您遇到(1,[3])
时,您可以在地图中快速找到(1,[1,2])
,并将它们组合以获得(1,[1,2,3])
,依此类推
对于这个特定的问题,有一个简短的解决方案,使用Data.Map
中的工具:
import qualified Data.Map.Strict as Map
gather :: (Ord a) => [(a, [Int])] -> [(a, [Int])]
gather = Map.toList . Map.fromListWith (++) . reverse
之后:
> gather [(1 , [1]) , (2 , [1]) , (3 , [1]) , (1 , [2]) , (3 , [2]) , (1 , [3])]
[(1,[1,2,3]),(2,[1]),(3,[1,2])]
这里,Map.fromListWith
运行键值对列表[(k,v)]
,并将它们逐个添加到新映射中。添加每一对时,如果密钥不在映射中,则会在该密钥下添加值(在您的情况下,是一个单例值,如[1]
或[2]
)。如果键已在映射中,则使用提供的函数(++)
(即,作为新的\u单例\u值++现有的\u值列表
)将新值与旧值组合。这样做的效果是从输入列表中以相反的顺序创建一个值列表,因此我使用reverse
对输入列表进行了预处理。(如果订单不重要,你应该放弃。)
此问题的一个更常见的变体是编写一个函数,该函数包含一组对:
[(1,1), (2,1), (3,1), (1,2), (3,2), (1,3)]
其中的值尚未列出。解决办法是一样的。您只需使用
map(\(k,v)->(k,[v])
对列表进行预处理。此解决方案包含在注释中提到的解决方案中。简单(且高效)方法是浏览Data.Map.fromListWith
或者,看看这是否回答了您的问题?我投票将此问题作为主题外的问题结束,因为堆栈溢出不是一种代码编写服务。