Skip to content

Instantly share code, notes, and snippets.

@souenzzo
Created July 26, 2021 11:51
Show Gist options
  • Save souenzzo/cb37af999d2ab76e68e465427f1f3cd9 to your computer and use it in GitHub Desktop.
Save souenzzo/cb37af999d2ab76e68e465427f1f3cd9 to your computer and use it in GitHub Desktop.
(defn select-as
[value query]
(letfn [(selector [{:keys [children]
:as node}
value]
(cond
(map? value) (into {}
(keep (fn [{:keys [key params]
:as node}]
(when-let [[_ v] (find value key)]
(let [v (if (contains? node :children)
(selector node (get value key))
v)]
(if (contains? params :as)
[(:as params) v]
[key v])))))
children)
(coll? value) (mapv (partial selector node)
value)
:else value))]
(selector (eql/query->ast query) value)))
(select-as {:a 42
:b [{:c 33}]} `[(:a {:as :b})
{(:b {:as :c}) [(:c {:as :d})]}])
=> {:b 42, :c [{:d 33}]}
@souenzzo
Copy link
Author

souenzzo commented Jul 26, 2021

Another idea:
an eql-xf library

(defn select-xforming
  [value xform query]
  (letfn [(selector [{:keys [children]
                      :as   node}
                     value]
            (cond
              (map? value) (into {}
                             (comp (keep (fn [{:keys [key]
                                               :as   node}]
                                           (when-let [[_ v] (find value key)]
                                             (let [v (if (contains? node :children)
                                                       (selector node (get value key))
                                                       v)]
                                               (assoc node :value v)))))
                               xform
                               (map (juxt :key :value)))
                             children)
              (coll? value) (mapv (partial selector node)
                              value)
              :else value))]
    (selector (eql/query->ast query) value)))
(select-xforming {:a 42
                  :b [{:c 33}]}
  (map (fn [{:keys [params key value]
             :as   node}]
         (assoc node
           :value (if (number? value)
                    (inc value)
                    value)
           :key (:as params key))))
  `[(:a {:as :b})
    {(:b {:as :c}) [(:c {:as :d})]}])

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