I reworked the code a bit to something I thought was easier to parse mentally. I also printed out some intermediate values to show the processing chain in action:
(ns tst.clj.core
(:use clojure.test tupelo.test)
(:require
[tupelo.core :as t]
[clojure.string :as str]
[clojure.pprint :refer [pprint]]
))
(t/refer-tupelo)
(t/print-versions)
(def data
[{:id 1 :first-name "John" :last-name "Dog" :age 14}
{:id 2 :first-name "Johnny" :last-name "Cat" :age 54}
{:id 3 :first-name "Joe" :last-name "Doggy" :age 34}
{:id 4 :first-name "Jerry" :last-name "Gyrfalcon" :age 12}
{:id 5 :first-name "Jenkins" :last-name "TheButler" :age 24}])
(defn case-insensitive-match [pat-str search-str]
(re-find (re-pattern (str "(?i)" pat-str)) search-str)) ; pattern like #"(?i)xyz" => case-insensitive search
(defn find-rec [rec-list pat-str field-kw]
(filter #(case-insensitive-match pat-str (str (get % field-kw))) rec-list))
(defn my-filter [rec-list strpat]
(let [firstname-matches (find-rec rec-list strpat :first-name)
lastname-matches (find-rec rec-list strpat :last-name)
age-matches (find-rec rec-list strpat :age)]
(println "-----------------------------------------------------------------------------")
(spyx firstname-matches)
(spyx lastname-matches)
(spyx age-matches)
(first (remove empty? [firstname-matches lastname-matches age-matches]))))
(newline) (pprint [:john (my-filter data "john")])
(newline) (pprint [:jo (my-filter data "jo")])
(newline) (pprint [:y (my-filter data "y")])
(newline) (pprint [:og (my-filter data "og")])
(newline) (pprint [:3 (my-filter data "3")])
(newline) (pprint [:7 (my-filter data "7")])
One thing I don't understand is searching by age and treating it like a string instead of a number. Note that str/upper-case
silently converts a number like 42
into a string "42"
. Here I forced it to be explicit.
I also used the regular expression pattern like #"(?i)abc"
which does a case-insensitive search for "abc".
The results are:
-----------------------------------------------------------------------------
firstname-matches => ({:id 1, :first-name "John", :last-name "Dog", :age 14} {:id 2, :first-name "Johnny", :last-name "Cat", :age 54})
lastname-matches => ()
age-matches => ()
[:john
({:id 1, :first-name "John", :last-name "Dog", :age 14}
{:id 2, :first-name "Johnny", :last-name "Cat", :age 54})]
-----------------------------------------------------------------------------
firstname-matches => ({:id 1, :first-name "John", :last-name "Dog", :age 14} {:id 2, :first-name "Johnny", :last-name "Cat", :age 54} {:id 3, :first-name "Joe", :last-name "Doggy", :age 34})
lastname-matches => ()
age-matches => ()
[:jo
({:id 1, :first-name "John", :last-name "Dog", :age 14}
{:id 2, :first-name "Johnny", :last-name "Cat", :age 54}
{:id 3, :first-name "Joe", :last-name "Doggy", :age 34})]
-----------------------------------------------------------------------------
firstname-matches => ({:id 2, :first-name "Johnny", :last-name "Cat", :age 54} {:id 4, :first-name "Jerry", :last-name "Gyrfalcon", :age 12})
lastname-matches => ({:id 3, :first-name "Joe", :last-name "Doggy", :age 34} {:id 4, :first-name "Jerry", :last-name "Gyrfalcon", :age 12})
age-matches => ()
[:y
({:id 2, :first-name "Johnny", :last-name "Cat", :age 54}
{:id 4, :first-name "Jerry", :last-name "Gyrfalcon", :age 12})]
-----------------------------------------------------------------------------
firstname-matches => ()
lastname-matches => ({:id 1, :first-name "John", :last-name "Dog", :age 14} {:id 3, :first-name "Joe", :last-name "Doggy", :age 34})
age-matches => ()
[:og
({:id 1, :first-name "John", :last-name "Dog", :age 14}
{:id 3, :first-name "Joe", :last-name "Doggy", :age 34})]
-----------------------------------------------------------------------------
firstname-matches => ()
lastname-matches => ()
age-matches => ({:id 3, :first-name "Joe", :last-name "Doggy", :age 34})
[:3 ({:id 3, :first-name "Joe", :last-name "Doggy", :age 34})]
-----------------------------------------------------------------------------
firstname-matches => ()
lastname-matches => ()
age-matches => ()
[:7 nil]