HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Converting Between Clojure Maps and Lists

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
clojuremapsbetweenlistsandconverting

Problem

In an attempt to learn better functional programing I've attempted to convert some Python to idiomatic Clojure, but I'm not sure how well I did with parts of it.

One thing I found myself doing a lot was destructuring a map into a list and then converting it back into a map as in the following example that takes a map of products and ratings (e.g. {:m1 3.5 :m2 2}) and a multiplier and multiplies each rating by the multiplier and returns a map with the corresponding products.

(defn corrected-prod [person multiplyer]
  (into {} (map (fn [[k v]] [k (* v multiplyer)]) person)))


Is there a better way to do this? For context you can reference the code on GitHub.

Solution

Here's a few other ways you can go about it:

(defn map-vals [f a-map]
  (zipmap (keys a-map) (map f (vals a-map))))

(defn map-vals [f a-map]
  (reduce-kv #(assoc %1 %2 (f %3)) {} a-map))


or if you're set on transients/into

(defn map-vals [f a-map]
  (persistent! (reduce-kv #(assoc! %1 %2 (f %3)) (transient {}) a-map)))


This is a use case that could maybe stand to have a more elegant core tool, though. Or at least, I'm not the only one to miss it.

For what it's worth, the zipmap approach actually appears to perform best in my cursory testing and is pretty clear in its intent to change the values while keeping the keys as they were. If you're using a function literal it also means that fn doesn't have to take keys it's not going to do anything interesting with, which could make it a little clearer.

Code Snippets

(defn map-vals [f a-map]
  (zipmap (keys a-map) (map f (vals a-map))))

(defn map-vals [f a-map]
  (reduce-kv #(assoc %1 %2 (f %3)) {} a-map))
(defn map-vals [f a-map]
  (persistent! (reduce-kv #(assoc! %1 %2 (f %3)) (transient {}) a-map)))

Context

StackExchange Code Review Q#101150, answer score: 2

Revisions (0)

No revisions yet.