title: How to filter vector of maps by multiple keys in Clojure
body: <p>Assume we have a datastructure like this one:</p>
  
  <pre><code>(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"}]))
  </code></pre>
  
  <p>I have learned how to filter it by one key, for example:</p>
  
  <pre><code>(defn my-filter
    [str-input]
    (filter #(re-find (-&gt;&gt; (str str-input)
                           (lower-case)
                           (re-pattern))
                           (lower-case (:first-name %)))
              @data))
  
  &gt; (my-filter "John1")
  &gt; ({:last-name "Dow1", :age "14", :first-name "John1", :id 1})
  </code></pre>
  
  <p>But now I'm a little bit confused on how to filter data by <code>:first-name</code>, <code>:last-name</code> and <code>:age</code> simple way?<br><br>
  <strong>Update</strong>: Sorry for being not too clear enough in explanation of what the problem is... Actually, I want all keys <code>:first-name</code>, <code>:last-name</code> and <code>:age</code> to paticipate in filter function, so that, if <code>str-input</code> doesn't match <code>:first-name</code>'s val, check if it matches <code>:last-name</code>'s val and so on.</p>
  
  <p><strong>Update 2</strong>:
  After trying <code>some-fn</code>, <code>every-pred</code> and <code>transducers</code>, I didn't get what I need, e.g. regex in filter predicates, I guess it's a lack of knowledge for now.
  So, I ended up with this function which works fine, but the code is ugly and duplicated. How I can get rid of code duplication?</p>
  
  <pre><code>(defn my-filter [str-input]
    (let [firstname (filter #(re-find (-&gt;&gt; (str str-input)
                                           (upper-case)
                                           (re-pattern))
                                      (upper-case (:first-name %)))
                       @data)
          lastname (filter #(re-find (-&gt;&gt; (str str-input)
                                          (upper-case)
                                          (re-pattern))
                                     (upper-case (:last-name %)))
                      @data)
          age (filter #(re-find (-&gt;&gt; (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)))))
  </code></pre>