如果我有2个哈斯克尔地图,例如:如何合并两张地图在Haskell
[("a",1),
("b",2),
("c",1)]
和
[("a",1)]
我怎么能以这样的方式,它将给写一个函数像这样:
[("a",2),("b",2),("c",1)]
到现在为止我只能写基本情况,但那都是。
如果我有2个哈斯克尔地图,例如:如何合并两张地图在Haskell
[("a",1),
("b",2),
("c",1)]
和
[("a",1)]
我怎么能以这样的方式,它将给写一个函数像这样:
[("a",2),("b",2),("c",1)]
到现在为止我只能写基本情况,但那都是。
如何unionWith
从Data.Map
?
这里有两幅地图m1
和m2
都包含密钥“A”使用它的样本GHCI会话:
Prelude> import qualified Data.Map as Map
Prelude Data.Map> let m1 = Map.fromList [('a', 1)]
Prelude Data.Map> let m2 = Map.fromList [('a', 2), ('b', 10)]
Prelude Data.Map> Map.unionWith (+) m1 m2
fromList [('a',3),('b',10)]
如果要定义自己的功能来包装所有了:
mergeMap :: (Ord k, Num a) => Map.Map k a -> Map.Map k a -> Map.Map k a
mergeMap = Map.unionWith (+)
其是相同
mergeMap a b = Map.unionWith (+) a b
甚至
a `mergeMap` b = Map.unionWith (+) a b
,你也可以让你想GHC推断mapUnion
的类型,但它会推断相同的类型。
注:在现实生活中,一定要做出,因此Data.Map.Strict.unionWith
和Data.Map.Lazy.unionWith
之间的懒惰和严格的地图之间的正确选择。
非常感谢。如果函数看起来像这样:bagSum :: M.Map String Int - > M.Map String Int - > M.Map String Int bagSum b1 b2 = M.unionWith(+)b1 b2 –
我编辑了回答这个答案。 –
并且应该调用mergeMap [(“a”,1),(“b”,2)] [(“a”,1),(“b”,2)] ???它说它不能绑定变量 –
Map
的替代方案是sort
。此版本假定每个键在每个列表中只出现一次。如果情况并非如此,你可以修复它,但Map
方法将开始看起来更有吸引力。
combine op xs ys = cs op (s xs) (s ys)
where
s = sortBy (compare `on` fst)
cs _ [] qs = qs
cs _ ps [] = ps
cs op [email protected]([email protected](pk,pv):ps) [email protected]([email protected](qk,qv):qs) =
case compare pk qk of
LT -> p : cs op ps qss
GT -> q : cs op pss qs
EQ -> (pk, pv `op` qv) : cs op ps qs
我认为重复键是重点。 –
@ErikAllik,当然有点难以确定 - 我们从一个例子来推理。我想象这些列表是为了代表地图,而且他们只需要合并。他们甚至可能已经被排序了。 – dfeuer
看起来你'Data.Map'需要'unionWith':'unionWith(+)MAP1 map2'。 – ach
如果您正在实施一个包,请考虑使用[multiset](http://hackage.haskell.org/package/multiset)包。 –