Lo primero que debe saber es que (la mayoría) de las estructuras de datos en clojure son inmutables y la mayoría de las funciones son, así, funcional. Eso significa que no tienen efectos secundarios. En su caso filter
no cambia la secuencia de ninguna manera, devuelve una nueva, que contiene solo los elementos no filtrados.
Así, para filtrar myseq
que hay que hacer algo como:
(def filtered-seq (filter (fn [x] ...) myseq))
Filtro llamará a la función en repetidas ocasiones, la unión x
para el elemento actualmente filtrada en myseq
. Es decir, la primera vez estará obligado a {:name "Peter" :rank 2222}
, luego a {:name "Anna" :rank 111}
. El filtered-seq
contendrá solo los elementos, para los cuales la función devolvió verdadero. myseq
no se modificará!
lo tanto, usted quiere dejar sólo los elementos con :rank
superior a 222:
(filter (fn [x] (> (:rank x) 222)) myseq)
eso es todo. Y una cosa más sobre el filtro es que es flojo. Es decir, los elementos de la colección devuelta se "realizan" (o computan) solo cuando se necesitan.
No necesita usar loop
para esto, ya que filter
hace el trabajo bien, y loop
no es flojo.
Dicho esto, su loop
no funciona porque tiene varios problemas:
recur
está fuera del loop
. En este caso, clojure volverá al principio de la función.
- que necesita para construir un valor de retorno y lo que necesita para mantener el elemento "actual"
- es necesario comprobar adecuadamente para la condición final
El código podría ser algo como esto (no probado):
(defn remove-lower [number myseq]
(loop [sq myseq res []]
(if (empty? sq)
res
(let [current (first sq)]
(if (> (:rank current) number)
(recur (rest sq) (conj res current))
(recur (rest sq) res))))))
Nota cómo:
recur
es ahora dentro de la loop
res
contiene el valor de retorno y sq
contiene la secuencia Actualmente izquierda
- cada
recur
pasa los nuevos valores de sq
y res
para la siguiente iteración
sq
es "shrinked" con cada iteración, por lo que el bucle con el tiempo se salir a menos que myseq
sea infinito. Contraste esto a filter
, que maneja secuencias infinitas muy bien.
Como ve, esto es más difícil de leer y menos general que filter
y también está ansioso (no flojo).
¡Aún mejor! Así es como intenté hacerlo primero, pero no tuve éxito. Gracias. –
'(filtro # (> (: rango%) 220) myseq)' – Ankur
Muchas gracias chicos, el código ahora está funcionando y muy rápido también! –