Cómo filtrar vectores de mapas por múltiples claves en Clojure
Supongamos que tenemos una estructura de datos como esta:
(def data
(atom [{:id 1 :first-name "John1" :last-name "Dow1" :age "14"}
{:id 2 :first-name "John2" :last-name "Dow2" :age "54"}
{:id 3 :first-name "John3" :last-name "Dow3" :age "34"}
{:id 4 :first-name "John4" :last-name "Dow4" :age "12"}
{:id 5 :first-name "John5" :last-name "Dow5" :age "24"}]))
Aprendí a filtrarlo por una tecla, por ejemplo:
(defn my-filter
[str-input]
(filter #(re-find (->> (str str-input)
(lower-case)
(re-pattern))
(lower-case (:first-name %)))
@data))
> (my-filter "John1")
> ({:last-name "Dow1", :age "14", :first-name "John1", :id 1})
Pero ahora estoy un poco confundido sobre cómo filtrar datos por:first-name
, :last-name
y:age
¿manera simple?
Actualizar: S, Orry por no ser lo suficientemente claro como para explicar cuál es el problema ... En realidad, quiero todas las claves:first-name
, :last-name
y:age
para participar en la función de filtro, de modo que, sistr-input
no coincide:first-name
's val, compruebe si coincide:last-name
Es val y así sucesivamente.
Actualización 2: Después de intentarsome-fn
, every-pred
ytransducers
, No obtuve lo que necesito, p. regex en predicados de filtro, supongo que es una falta de conocimiento por ahora. Entonces, terminé con esta función que funciona bien, pero el código es feo y está duplicado. ¿Cómo puedo deshacerme de la duplicación de código?
(defn my-filter [str-input]
(let [firstname (filter #(re-find (->> (str str-input)
(upper-case)
(re-pattern))
(upper-case (:first-name %)))
@data)
lastname (filter #(re-find (->> (str str-input)
(upper-case)
(re-pattern))
(upper-case (:last-name %)))
@data)
age (filter #(re-find (->> (str str-input)
(upper-case)
(re-pattern))
(upper-case (:age %)))
@data)]
(if-not (empty? firstname)
firstname
(if-not (empty? lastname)
lastname
(if-not (empty? age)
age)))))