如果我有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)包。 –