He escrito una función que usa la recursividad para encontrar el número de elementos en una lista y funciona con éxito, sin embargo, no me gusta particularmente la forma en que la he escrito. Ahora lo he escrito de una manera que parece que no puedo pensar en una forma diferente de hacerlo.

Mi código está a continuación:

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

Para mí parece que es demasiado complicado, ¿alguien puede pensar en otra forma en que esto se pueda escribir para comparar?

Cualquier ayuda muy apreciada.

0
benjano 3 ene. 2017 a las 19:08

4 respuestas

La mejor respuesta

Aquí hay una versión recursiva ingenua:

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

Tenga en cuenta que no habrá ninguna optimización de llamada de cola aquí, por lo que para listas largas la pila se desbordará.

Aquí hay una versión con reduce:

(defn my-count [coll]
    (reduce (fn [acc x] (inc acc)) 0 coll))
2
z7sg Ѫ 3 ene. 2017 a las 17:12

Aquí hay uno que está optimizado y no depende de loop. Básicamente igual que el primero de Alan Thompson, pero las funciones internas son lo mejor. (Y me siento más idiomático) :-)

(defn my-count [sq]
 (letfn [(inner-count [c s]
          (if (empty? s) 
           c
           (recur (inc c) (rest s))))]
  (inner-count 0 sq)))
1
Paul Gowder 4 ene. 2017 a las 05:50

Aquí hay un código que muestra algunas soluciones diferentes. Normalmente, debe usar la función integrada 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))))
2
amalloy 3 ene. 2017 a las 17:33

Solo para completar, aquí hay otro giro

(defn my-count
  ([data]
   (my-count data 0))
  ([data counter]
   (if (empty? data)
     counter
     (recur (rest data) (inc counter)))))
0
Tim X 4 ene. 2017 a las 02:33