viebel
viebel

Reputation: 20670

In clojure, how to map a sequence and create a hash-map

In clojure, I would like to apply a function to all the elements of a sequence and return a map with the results where the keys are the elements of the sequence and the values are the elements of the mapped sequence.

I have written the following function function. But I am wondering why such a function is not part of clojure. Maybe it's not idiomatic?

(defn map-to-object[f lst]
   (zipmap lst (map f lst)))


(map-to-object #(+ 2 %) [1 2 3]) => {1 3, 2 4, 3 5}

Upvotes: 0

Views: 480

Answers (2)

A. Webb
A. Webb

Reputation: 26446

My comments were going to get too long winded, so...

  1. Nothing wrong with your code whatsoever.
  2. You might also see (into {} (map (juxt identity f) coll))
  3. One common reason for doing this is to cache the results of a function over some inputs.
  4. There are other use-cases for what you have done, e.g. when a hash-map is specifically needed.
  5. If and only if #3 happens to be your use case, then memoize does this for you.

If the function is f, and the resultant map is m then (f x) and (m x) have the same value in the domain. However, the values of (m x) have been precalculated, in other words, memoized.

Indeed memoize does exactly the same thing behind the scene, it just doesn't give direct access to the map. Here's a tiny modification to the source of memoize to see this.

(defn my-memoize
  "Exactly the same as memoize but the cache memory atom must
  be supplied as an argument."
  [f mem]
  (fn [& args]
    (if-let [e (find @mem args)]
      (val e)
      (let [ret (apply f args)]
        (swap! mem assoc args ret)
        ret))))

Now, to demonstrate

(defn my-map-to-coll [f coll] 
  (let [m (atom {})
        g (my-memoize f m)]
    (doseq [x coll] (g x))
    @m))

And, as in your example

(my-map-to-coll #(+ 2 %) [1 2 3])
;=> {(3) 5, (2) 4, (1) 3}

But note that the argument(s) are enclosed in a sequence as memoize handles multiple arity functions as well.

Upvotes: 2

DanLebrero
DanLebrero

Reputation: 8593

Your function is perfectly idiomatic.

For a fn to be part of core, I think it has to be useful to most people. What is part of the core language and what is not is quite debatable. Just think about the amount of StringUtils classes that you can find in Java.

Upvotes: 2

Related Questions