Last active
June 9, 2019 18:02
-
-
Save danielneal/081b320631da733f66d9e49b60af2341 to your computer and use it in GitHub Desktop.
Minimal query for maps
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns query.core) | |
(defn paths | |
([q] | |
(paths [] {} q)) | |
([current-path m q] | |
(letfn [(paths-map | |
[current-path m q] | |
(apply merge (for [[k v] q] | |
(paths (conj current-path k) {} v)))) | |
(paths-vec | |
[current-path m q] | |
(apply merge (for [v q] | |
(if (map? v) | |
(paths-map current-path {} v) | |
(paths (conj current-path v) {} v)))))] | |
(cond | |
(map? q) (paths-map current-path m q) | |
(vector? q) (paths-vec current-path m q) | |
:else {q current-path})))) | |
(defn query-fn | |
[q] | |
(let [paths (paths q)] | |
(fn [db] | |
(reduce-kv (fn [m k v] (assoc m k (get-in db v))) {} paths)))) | |
(defn query | |
[db q] | |
(let [f (query-fn q)] | |
(f db))) | |
(comment | |
(query | |
{:products/by-id {1 {:product/id 1 | |
:product/sku "FINMOD001" | |
:product/nutrition {:energy "100kcal" | |
:salt "1g"}}}} | |
{:products/by-id {1 [:product/id :product/sku :product/nutrition]}}) | |
#:product{:id 1, :sku "FINMOD001", :nutrition {:energy "100kcal", :salt "1g"}}) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment