Skip to content

Commit c2788df

Browse files
author
RyanGlScott
committed
Implement intersectionWithKey for HashMap
1 parent 91877c7 commit c2788df

File tree

4 files changed

+37
-1
lines changed

4 files changed

+37
-1
lines changed

Data/HashMap/Base.hs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ module Data.HashMap.Base
4545
, difference
4646
, intersection
4747
, intersectionWith
48+
, intersectionWithKey
4849

4950
-- * Folds
5051
, foldl'
@@ -801,6 +802,18 @@ intersectionWith f a b = foldlWithKey' go empty a
801802
_ -> m
802803
{-# INLINABLE intersectionWith #-}
803804

805+
-- | /O(n+m)/ Intersection of two maps. If a key occurs in both maps
806+
-- the provided function is used to combine the values from the two
807+
-- maps.
808+
intersectionWithKey :: (Eq k, Hashable k) => (k -> v1 -> v2 -> v3)
809+
-> HashMap k v1 -> HashMap k v2 -> HashMap k v3
810+
intersectionWithKey f a b = foldlWithKey' go empty a
811+
where
812+
go m k v = case lookup k b of
813+
Just w -> insert k (f k v w) m
814+
_ -> m
815+
{-# INLINABLE intersectionWithKey #-}
816+
804817
------------------------------------------------------------------------
805818
-- * Folds
806819

Data/HashMap/Lazy.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ module Data.HashMap.Lazy
6565
, difference
6666
, intersection
6767
, intersectionWith
68+
, intersectionWithKey
6869

6970
-- * Folds
7071
, foldl'

Data/HashMap/Strict.hs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ module Data.HashMap.Strict
6565
, difference
6666
, intersection
6767
, intersectionWith
68+
, intersectionWithKey
6869

6970
-- * Folds
7071
, foldl'
@@ -97,7 +98,8 @@ import qualified Data.HashMap.Array as A
9798
import qualified Data.HashMap.Base as HM
9899
import Data.HashMap.Base hiding (
99100
alter, adjust, fromList, fromListWith, insert, insertWith, intersectionWith,
100-
map, mapWithKey, mapMaybe, mapMaybeWithKey, singleton, update, unionWith)
101+
intersectionWithKey, map, mapWithKey, mapMaybe, mapMaybeWithKey, singleton,
102+
update, unionWith)
101103
import Data.HashMap.Unsafe (runST)
102104

103105
-- $strictness
@@ -396,6 +398,18 @@ intersectionWith f a b = foldlWithKey' go empty a
396398
_ -> m
397399
{-# INLINABLE intersectionWith #-}
398400

401+
-- | /O(n+m)/ Intersection of two maps. If a key occurs in both maps
402+
-- the provided function is used to combine the values from the two
403+
-- maps.
404+
intersectionWithKey :: (Eq k, Hashable k) => (k -> v1 -> v2 -> v3)
405+
-> HashMap k v1 -> HashMap k v2 -> HashMap k v3
406+
intersectionWithKey f a b = foldlWithKey' go empty a
407+
where
408+
go m k v = case HM.lookup k b of
409+
Just w -> insert k (f k v w) m
410+
_ -> m
411+
{-# INLINABLE intersectionWithKey #-}
412+
399413
------------------------------------------------------------------------
400414
-- ** Lists
401415

tests/HashMapProperties.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,13 @@ pIntersectionWith :: [(Key, Int)] -> [(Key, Int)] -> Bool
149149
pIntersectionWith xs ys = M.intersectionWith (-) (M.fromList xs) `eq_`
150150
HM.intersectionWith (-) (HM.fromList xs) $ ys
151151

152+
pIntersectionWithKey :: [(Key, Int)] -> [(Key, Int)] -> Bool
153+
pIntersectionWithKey xs ys = M.intersectionWithKey go (M.fromList xs) `eq_`
154+
HM.intersectionWithKey go (HM.fromList xs) $ ys
155+
where
156+
go :: Key -> Int -> Int -> Int
157+
go (K k) i1 i2 = k - i1 - i2
158+
152159
------------------------------------------------------------------------
153160
-- ** Folds
154161

@@ -255,6 +262,7 @@ tests =
255262
[ testProperty "difference" pDifference
256263
, testProperty "intersection" pIntersection
257264
, testProperty "intersectionWith" pIntersectionWith
265+
, testProperty "intersectionWithKey" pIntersectionWithKey
258266
]
259267
-- Filter
260268
, testGroup "filter"

0 commit comments

Comments
 (0)