简体   繁体   English

Clojure-使用递归查找列表中的元素数

[英]Clojure - Using recursion to find the number of elements in a list

I have written a function that uses recursion to find the number of elements in a list and it works successfully however, I don't particularly like the way I've written it. 我编写了一个函数,该函数使用递归来查找列表中的元素数量,并且可以成功运行,但是,我并不特别喜欢编写它的方式。 Now I've written it one way I can't seem to think of a different way of doing it. 现在,我已经以一种似乎无法想到的另一种方式来编写它。

My code is below: 我的代码如下:

(def length 
 (fn [n]
  (loop [i n total 0]
   (cond (= 0 i) total
     :t (recur (rest i)(inc total)))))) 

To me it seems like it is over complicated, can anyone think of another way this can be written for comparison? 在我看来,这似乎太复杂了,任何人都可以想到另一种可以比较的方式吗?

Any help greatly appreciated. 任何帮助,不胜感激。

Here is code showing some different solutions. 这是显示一些不同解决方案的代码。 Normally, you should use the built-in function count . 通常,您应该使用内置函数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))))

Here is a naive recursive version: 这是一个朴素的递归版本:

(defn my-count [coll]
    (if (empty? coll) 
        0 
        (inc (my-count (rest coll)))))

Bear in mind there's not going to be any tail call optimization going on here so for long lists the stack will overflow. 请记住,此处不会进行任何尾部调用优化,因此对于较长的列表,堆栈将溢出。

Here is a version using reduce : 这是使用reduce的版本:

(defn my-count [coll]
    (reduce (fn [acc x] (inc acc)) 0 coll))

Here's one that is tail-call optimized, and doesn't rely on loop . 这是经过尾调用优化的,并且不依赖loop Basically the same as Alan Thompson's first one, but inner functions are the best things. 基本上与艾伦·汤普森(Alan Thompson)的第一个相同,但是内部功能才是最好的。 (And feel more idiomatic to me.) :-) (并且对我来说更习惯):-)

(defn my-count [sq]
 (letfn [(inner-count [c s]
          (if (empty? s) 
           c
           (recur (inc c) (rest s))))]
  (inner-count 0 sq)))

Just for completeness, here is another twist 只是为了完整性,这是另一种变化

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM