有没有更简洁的方法来编写循环,更新和返回地图的Clojure函数?

时间:2012-05-10 12:12:47

标签: clojure

这个功能有效,但我正在学习Clojure,想知道是否有更好/更清晰的方法来写这个:

;; 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")

更新:这是我最终使用的内容:

(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 个答案:

答案 0 :(得分:4)

(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) )))

答案 1 :(得分:2)

我会通过以下方式执行此操作:

(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)))

当我必须收集一个集合并返回不同类型的集合时,这是我遵循的“模式”。这里我们有一个方法列表,我们想将这个列表转换成一个映射(在对它进行一些处理之后)。我觉得reduce是最可读的方法。

答案 2 :(得分:2)

我会使用mapget-methods返回的每个条目构建哈希映射,然后将merge所有这些哈希映射构建为一个。

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

通常最好使用标准序列操作函数,如mapfilter等,而不是loop