Search code examples
dictionaryfilterclojurereduceclojurescript

How to parallel filter data by value's truthy in Clojure?


We have some data like this:

(def x {:title ["NAME" "CODE" "ORDER" "MIN" "MAX" "IMG"]
        :show-in-list [true true true true false false]
        :key [:name :code :order :min :max :image]
        :input-type [:txt :txt :num :num :num :img]
        :value [nil nil nil nil nil nil]
        :required [true true false false false false]})

We want to filter these values by :required's bool value which results in:

{:title ["NAME" "CODE"],
 :show-in-list [true true],
 :key [:part_name :part_code],
 :input-type [:txt :txt],
 :value [nil nil],
 :required [true true]}

Solution

  • You can filter each element with ':required' vector:

    (let [x {:title        ["NAME" "CODE" "ORDER" "MIN" "MAX" "IMG"]
             :show-in-list [true false true true false false]
             :key          [:name :code :order :min :max :image]
             :input-type   [:txt :txt :num :num :num :img]
             :value        [nil nil nil nil nil nil]
             :required     [true true false false false false]}]
      (->> x
           (map (fn [[k v]]
                  ;; value v (which is a vector) is filtered out by its :required filter
                  [k  (->> (map #(if %1 %2 ::false) (:required x) v)
                           ;; remove ::false element
                           (remove #(= ::false %)))]))
           ;; add the updated key-value pair
           (into (empty x))))
    

    returns...

    {:title        ("NAME" "CODE"),
     :show-in-list (true false),
     :key          (:name :code),
     :input-type   (:txt :txt),
     :value        (nil nil),
     :required     (true true)}