Is there a cleaner way to write this Clojure function that loops, updates, and returns a map?

This function works, but I am involved in the learning process of Clojure and want to know if there is a better / cleaner way to write this:

;; loop over methods, update the scripts map, and return scripts

(defn update-scripts
  [filename]
  (loop [scripts {}
         methods (get-methods filename)]
    (if (seq methods)
      (let [method (first methods)
            sig (get-method-signature method)
            name (get-method-name sig)]
        (recur (assoc scripts name {:sig sig, :method method})
               (rest methods)))
      scripts)))


(update-scripts "gremlin.groovy")

UPDATE: this is what I ended up using:

(defn- update-scripts
  [scripts method]
  (let [sig (get-method-signature method)
        name (get-method-name sig)]
    (assoc scripts name {:sig sig :method method})))

(defn get-scripts
  [filename]
  (reduce update-scripts {} (get-methods filename)))
+3
source share
3 answers

I would do it with a reduction as follows:

(defn update-scripts
  [filename]
  (reduce (fn [scripts method]
            (let [sig (get-method-signature method)
                  name (get-method-name sig)]
              (assoc scripts name {:sig sig :method method})))
          {}
          (get-methods filename)))

This is the “template” that I follow when I need to take a collection and return a collection of a different type. Here we have a list of methods, and we want to convert this list to a map (after doing some processing on it). I feel that cutting is the most readable way to do this.

+2
source
(defn update-scripts
  [filename]
  (into {} (map (fn [m] [ (get-method-name (get-method-signature m)) {:sig (get-method-signature m), :method m}  ] ) (get-methods filename) )))
+4
source

map - , get-methods, merge - .

(defn update-scripts
  [filename]
  (apply merge
         (map
          #(hash-map (get-method-name %) {:sig (get-method-signature %) :method %})
          (get-methods filename))))

As a rule, it is better to use standard sequence processing functions such as map, filteretc. instead of loop.

+2
source

All Articles