Skip to content

Instantly share code, notes, and snippets.

@visibletrap
Last active March 6, 2021 03:50
Show Gist options
  • Save visibletrap/34b29af24eb33acaf69b1f136c0077a3 to your computer and use it in GitHub Desktop.
Save visibletrap/34b29af24eb33acaf69b1f136c0077a3 to your computer and use it in GitHub Desktop.
(ns rules-to-pred)
(def products
[{:id 1
:department "bedding"
:category "pillow"
:color "white"}
{:id 2
:department "cloth"
:category "shirt"
:color "red"}
{:id 3
:department "kids"
:category "bottle"}
{:id 4
:department "cloth"
:category "t-shirt"
:color "white"}
{:id 5
:department "kids"
:category "onesie"
:color "white"}
{:id 6
:department "cloth"
:category "pants"
:color "black"}
{:id 7
:department "kids"
:category "pants"
:color "black"}
{:id 8
:department "cloth"
:category "shirt"
:color "white"}])
(def rules
[{:condition :match
:attr :department
:value ["cloth" "kids"]
:required true}
{:condition :not-match
:attr :category
:value ["t-shirt" "shorts"]
:required true}
{:condition :not-match
:attr :department
:value "kids"
:required true}
{:condition :match
:attr :color
:value "black"}
{:condition :match
:attr :color
:value "white"}])
; For rules without `:required true`, product needs to be satisfied at least one of them.
(defn rules->pred-fn
[rules]
; Implement me
)
(= (mapv :id (filter (rules->pred-fn rules) products))
[6 8])
@visibletrap
Copy link
Author

อันนี้ของผมครับ มีเช็ค empty ไว้ด้วย เพราะในงานที่ทำมีกรณี empty จริงๆ ครับ

(defn rule->pred-fn
  [{:keys [value condition attr]}]
  (let [value-set (if (coll? value) (set value) #{value})]
    (case condition
      :match (fn [item]
               (contains? value-set (get item attr)))
      :not-match (fn [item]
                   (not (contains? value-set (get item attr)))))))

(defn rules->pred-fn
  [rules]
  (let [{:keys [required not-required]} (group-by (fn [{:keys [required]}] (if required :required :not-required)) rules)
        required-fn (when (seq required) (apply every-pred (mapv rule->pred-fn required)))
        not-required-fn (when (seq not-required) (apply some-fn (map rule->pred-fn not-required)))]
    (apply every-pred (remove nil? [required-fn not-required-fn]))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment