Mapping maps
2014-07-01
versatile utility function
Når jeg jobber med Clojure kommer jeg av og til bort i tilfeller hvor jeg har en map og ønsker å transformere nøklene eller verdiene i mappet. Overraskende nok så har jeg ikke funnet noen funksjoner som tilbyr dette ut av boksen i de innebygde Clojure-bibliotekene.
Så hvordan transformerer man alle verdiene, mens man samtidig beholder nøklene i map'et? Zipmap er en fin funksjon å bruke til dette.
(defn map-vals [f m]
(zipmap (keys m)
(map f (vals m))))
Eksempel:
(map-vals inc {:a 1, :b 2})
=> {:a 2, :b 3}
Tilsvarende, hvordan transformerer man nøklene mens man beholder verdiene i map'et? Igjen passer zipmap som hånd i hanske.
(defn map-keys [f m]
(zipmap (map f (keys m))
(vals m)))
Eksempel:
(map-keys inc {1 "a", 2 "b"})
=> {2 "a", 3 "b"}
Avslutningsvis så er det kjekt å ha en funksjon som mapper over både nøkler og verdier samtidig, så slipper vi gjøre det i to operasjoner.
(defn map-keys-vals [kfn vfn m]
(zipmap (map kfn (keys m))
(map vfn (vals m))))
Eksempel:
(map-keys-vals inc inc {1 1, 2 2})
=> {2 2, 3 3}