From 6d028cbe2425f7c905c6fe4a88aa9e927161e902 Mon Sep 17 00:00:00 2001 From: Nathan Marz Date: Mon, 22 Jun 2015 14:37:39 -0400 Subject: [PATCH] change filterer so it accepts a path that acts like selected? --- src/clj/com/rpl/specter.clj | 2 +- src/clj/com/rpl/specter/impl.clj | 41 +++++++++++++++++++------------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/clj/com/rpl/specter.clj b/src/clj/com/rpl/specter.clj index 71da0e7..d46c448 100644 --- a/src/clj/com/rpl/specter.clj +++ b/src/clj/com/rpl/specter.clj @@ -129,7 +129,7 @@ (defn codewalker [afn] (->CodeWalkerStructurePath afn)) -(defn filterer [afn] (->FilterStructurePath afn)) +(defn filterer [& path] (->FilterStructurePath (comp-paths* path))) (defn keypath [akey] (->KeyPath akey)) diff --git a/src/clj/com/rpl/specter/impl.clj b/src/clj/com/rpl/specter/impl.clj index 14e6d99..8113b79 100644 --- a/src/clj/com/rpl/specter/impl.clj +++ b/src/clj/com/rpl/specter/impl.clj @@ -301,6 +301,25 @@ (defn- conj-all! [cell elems] (set-cell! cell (concat (get-cell cell) elems))) +(defn compiled-select* + [^com.rpl.specter.impl.TransformFunctions tfns structure] + (let [^com.rpl.specter.impl.ExecutorFunctions ex (.executors tfns)] + ((.select-executor ex) (.selector tfns) structure) + )) + +(defn compiled-update* + [^com.rpl.specter.impl.TransformFunctions tfns update-fn structure] + (let [^com.rpl.specter.impl.ExecutorFunctions ex (.executors tfns)] + ((.update-executor ex) (.updater tfns) update-fn structure) + )) + +(defn selected?* + [compiled-path structure] + (->> structure + (compiled-select* compiled-path) + empty? + not)) + ;; returns vector of all results (defn- walk-select [pred continue-fn structure] (let [ret (mutable-cell []) @@ -313,12 +332,12 @@ (get-cell ret) )) -(defn- filter+ancestry [afn aseq] +(defn- filter+ancestry [path aseq] (let [aseq (vec aseq)] (reduce (fn [[s m :as orig] i] (let [e (get aseq i) pos (count s)] - (if (afn e) + (if (selected?* path e) [(conj s e) (assoc m pos i)] orig ))) @@ -391,14 +410,14 @@ (codewalk-until (.afn this) next-fn structure))) -(deftype FilterStructurePath [afn]) +(deftype FilterStructurePath [path]) (extend-protocol StructurePath FilterStructurePath (select* [^FilterStructurePath this structure next-fn] - (->> structure (filter (.afn this)) doall next-fn)) + (->> structure (filter #(selected?* (.path this) %)) doall next-fn)) (update* [^FilterStructurePath this structure next-fn] - (let [[filtered ancestry] (filter+ancestry (.afn this) structure) + (let [[filtered ancestry] (filter+ancestry (.path this) structure) ;; the vec is necessary so that we can get by index later ;; (can't get by index for cons'd lists) next (vec (next-fn filtered))] @@ -473,18 +492,6 @@ (next-fn structure) )) -(defn compiled-select* - [^com.rpl.specter.impl.TransformFunctions tfns structure] - (let [^com.rpl.specter.impl.ExecutorFunctions ex (.executors tfns)] - ((.select-executor ex) (.selector tfns) structure) - )) - -(defn compiled-update* - [^com.rpl.specter.impl.TransformFunctions tfns update-fn structure] - (let [^com.rpl.specter.impl.ExecutorFunctions ex (.executors tfns)] - ((.update-executor ex) (.updater tfns) update-fn structure) - )) - (deftype ConditionalPath [cond-pairs]) (defn- retrieve-selector [cond-pairs structure]