[英]Clojure - Using recursion to find the number of elements in a list
我编写了一个函数,该函数使用递归来查找列表中的元素数量,并且可以成功运行,但是,我并不特别喜欢编写它的方式。 现在,我已经以一种似乎无法想到的另一种方式来编写它。
我的代码如下:
(def length
(fn [n]
(loop [i n total 0]
(cond (= 0 i) total
:t (recur (rest i)(inc total))))))
在我看来,这似乎太复杂了,任何人都可以想到另一种可以比较的方式吗?
任何帮助,不胜感激。
这是显示一些不同解决方案的代码。 通常,您应该使用内置函数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))))
这是一个朴素的递归版本:
(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))
这是经过尾调用优化的,并且不依赖loop
。 基本上与艾伦·汤普森(Alan Thompson)的第一个相同,但是内部功能才是最好的。 (并且对我来说更习惯):-)
(defn my-count [sq]
(letfn [(inner-count [c s]
(if (empty? s)
c
(recur (inc c) (rest s))))]
(inner-count 0 sq)))
只是为了完整性,这是另一种变化
(defn my-count
([data]
(my-count data 0))
([data counter]
(if (empty? data)
counter
(recur (rest data) (inc counter)))))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.