我编写了一个函数,它使用递归来查找列表中的元素数量并且它成功运行但是,我并不特别喜欢我编写它的方式。现在我已经用一种方式编写了它,我似乎无法想到采用不同的方式。
我的代码如下:
(def length
(fn [n]
(loop [i n total 0]
(cond (= 0 i) total
:t (recur (rest i)(inc total))))))
对我来说,似乎它过于复杂,任何人都可以想到另一种可以写作比较的方法吗?
非常感谢任何帮助。
答案 0 :(得分:2)
以下代码显示了一些不同的解决方案。通常,您应该使用内置函数count
。
(def data [:one :two :three])
(defn count-loop [data]
(loop [cnt 0
remaining data]
(if (empty? remaining)
cnt
(recur (inc cnt) (rest remaining)))))
(defn count-recursive [remaining]
(if (empty? remaining)
0
(inc (count-recursive (rest remaining)))))
(defn count-imperative [data]
(let [cnt (atom 0)]
(doseq [elem data]
(swap! cnt inc))
@cnt))
(deftest t-count
(is (= 3 (count data)))
(is (= 3 (count-loop data)))
(is (= 3 (count-recursive data)))
(is (= 3 (count-imperative data))))
答案 1 :(得分:2)
这是一个天真的递归版本:
(defn my-count [coll]
(if (empty? coll)
0
(inc (my-count (rest coll)))))
请记住,这里不会有任何尾调用优化,所以对于长列表,堆栈会溢出。
以下是使用reduce
的版本:
(defn my-count [coll]
(reduce (fn [acc x] (inc acc)) 0 coll))
答案 2 :(得分:1)
这是一个尾调优化的,并且不依赖于controller
。基本上与Alan Thompson的第一个相同,但内在功能是最好的。 (并且对我来说感觉更加惯用。):-)
loop
答案 3 :(得分:0)
为了完整起见,这是另一个转折
(defn my-count
([data]
(my-count data 0))
([data counter]
(if (empty? data)
counter
(recur (rest data) (inc counter)))))