11module Dict.Extra exposing
22 ( groupBy, filterGroupBy, fromListBy, fromListCombining, fromListByCombining, frequencies
3- , removeWhen, removeMany, keepOnly, insertCombining, mapKeys, filterMap, invert
3+ , removeWhen, removeMany, keepOnly, insertCombining, updateIfExists, upsert, invert, invertAll
4+ , mapKeys, filterMap
45 , any, all
56 , find
67 , unionWith
@@ -16,7 +17,12 @@ module Dict.Extra exposing
1617
1718# Manipulation
1819
19- @docs removeWhen, removeMany, keepOnly, insertCombining, mapKeys, filterMap, invert
20+ @docs removeWhen, removeMany, keepOnly, insertCombining, updateIfExists, upsert, invert, invertAll
21+
22+
23+ # Maps
24+
25+ @docs mapKeys, filterMap
2026
2127
2228# Predicates
@@ -243,6 +249,46 @@ insertCombining combine key value dict =
243249 Dict . update key with dict
244250
245251
252+ {- | Updates a value if the key is present in the dictionary, leaves the dictionary untouched otherwise.
253+
254+ import Dict
255+
256+ Dict.fromList [ ( "expenses", 38.25 ), ( "assets", 100.85 ) ]
257+ |> updateIfExists "expenses" (\amount -> amount + 2.50)
258+ |> updateIfExists "liabilities" (\amount -> amount - 2.50)
259+ --> Dict.fromList [ ( "expenses", 40.75 ), ( "assets", 100.85 ) ]
260+
261+ -}
262+ updateIfExists : comparable -> (a -> a ) -> Dict comparable a -> Dict comparable a
263+ updateIfExists key f dict =
264+ case Dict . get key dict of
265+ Just value ->
266+ Dict . insert key ( f value) dict
267+
268+ Nothing ->
269+ dict
270+
271+
272+ {- | Updates a value if the key is present in the dictionary, inserts a new key-value pair otherwise.
273+
274+ import Dict
275+
276+ Dict.fromList [ ( "expenses", 38.25 ), ( "assets", 100.85 ) ]
277+ |> upsert "expenses" 4.50 (\amount -> amount + 2.50)
278+ |> upsert "liabilities" 2.50 (\amount -> amount - 2.50)
279+ --> Dict.fromList [ ( "expenses", 40.75 ), ( "assets", 100.85 ), ( "liabilities", 2.50 ) ]
280+
281+ -}
282+ upsert : comparable -> a -> (a -> a ) -> Dict comparable a -> Dict comparable a
283+ upsert key value f dict =
284+ case Dict . get key dict of
285+ Just oldValue ->
286+ Dict . insert key ( f oldValue) dict
287+
288+ Nothing ->
289+ Dict . insert key value dict
290+
291+
246292{- | Keep a key-value pair if its key appears in the set.
247293
248294 import Dict
@@ -337,6 +383,31 @@ invert dict =
337383 dict
338384
339385
386+ {- | Like `invert`, it changes the keys and values. However, if one value maps to multiple keys, then all of the keys will be retained.
387+
388+ import Dict
389+ import Set
390+
391+ Dict.fromList [ ( 1, "Jill" ), ( 2, "Jill" ), ( 3, "Jack" ) ]
392+ |> invertAll
393+ --> Dict.fromList [ ( "Jill", Set.fromList [ 1, 2 ] ), ( "Jack", Set.singleton 3 ) ]
394+
395+ -}
396+ invertAll : Dict comparable1 comparable2 -> Dict comparable2 (Set comparable1 )
397+ invertAll dict =
398+ Dict . foldl
399+ ( \ k v acc ->
400+ case Dict . get v acc of
401+ Just set ->
402+ Dict . insert v ( Set . insert k set) acc
403+
404+ Nothing ->
405+ Dict . insert v ( Set . singleton k) acc
406+ )
407+ Dict . empty
408+ dict
409+
410+
340411{- | Determine if any key/value pair satisfies some test.
341412
342413 import Dict
0 commit comments