如何在clojure中调用2个顺序函数?

时间:2014-08-13 16:33:38

标签: recursion clojure

我试图在https://iloveponies.github.io/120-hour-epic-sax-marathon/recursion.html做练习20。这是我的代码:

(defn my-frequencies-helper [freqs a-seq]
  (let [first-elem (first a-seq)
        rest-of-seq (rest a-seq)]
    (if (nil? first-elem)
      freqs
      (if (contains? freqs first-elem)
        (assoc freqs first-elem (inc (get freqs first-elem)))
        (assoc freqs first-elem 1)))))

(defn my-frequencies [a-seq]
  (my-frequencies-helper {} a-seq))

问题是这不是递归的。不知何故,我需要在更新my-frequencies-helper地图后将以下行添加到freqs

(my-frequencies-helper freqs rest-of-seq)

由于它不依赖于if函数的分支,因此我无法在不向if函数添加太多参数的情况下查看如何执行此操作。即它不适合condif,因为它是我在执行另一个功能上无关的步骤后要调用的一个步骤。

我可能错了,但是我只是想在更新地图之后递归调用my-frequencies-helper,例如在python中:

freqs[first-elem] = freqs[first-elem] + 1
my-frequencies-helper(freqs, rest-of-seq)          # just another step to execute

我如何将其与我的代码联系起来(或者更可能的是,这将是另一种简单的方法)?

2 个答案:

答案 0 :(得分:4)

我们可以在解构的帮助下简化这段代码:

(defn my-frequencies-helper
  [freqs [first-elem & rest-of-seq :as a-seq]]
    (if (empty? a-seq)
      freqs
      (let [updated-freqs (if (contains? freqs first-elem)
                            (assoc freqs first-elem (inc (get freqs first-elem)))
                            (assoc freqs first-elem 1))]
        (my-frequencies-helper updated-freqs rest-of-seq))))

此外还有一个常见的习惯用语

(if (contains? freqs first-elem)
  (assoc freqs first-elem (inc (get freqs first-elem)))
  (assoc freqs first-elem 1))

以下是等效的,只要您不将nil存储在其中一个数字的位置:

(update-in freqs [first-elem] (fnil inc 0))

这给我们留下了以下简化函数:

(defn my-frequencies-helper
  [freqs [first-elem & rest-of-seq :as a-seq]]
    (if (empty? a-seq)
      freqs
      (my-frequencies-helper (update-in freqs [first-elem] (fnil inc 0)) rest-of-seq)))

答案 1 :(得分:0)

对于列表中的每个项目,您都希望在结果词典中查找,看看该项目是否已经存在,如果是,您将保存+1,如果不是,只需在该字典中存储1。

有了这个,您可以通过简单的递归来解决它,或者使用reduce。

扰流:

  

(defn my-frequencies [x] (reduce(fn[t n](assoc t n (inc(get t n 0)))) {} x))