diff --git a/CHANGES.md b/CHANGES.md index e545b43..004230e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ * More efficient inline caching for Clojure version, now inline caching is always within 5% of manually precompiled code * Huge performance improvement for ALL transform on maps and vectors * Significant performance improvements for FIRST/LAST for vectors -* Huge performance improvements for `if-path` and `cond-path`, especially for condition path containing only static functions +* Huge performance improvements for `if-path`, `cond-path`, `selected?`, and `not-selected?`, especially for condition path containing only static functions * Eliminated compiler warnings for ClojureScript version * Dropped support for Clojurescript below v1.7.10 * Added :notpath metadata to signify pathedfn arguments that should be treated as regular arguments during inline factoring. If one of these arguments is not a static var reference or a non-collection value, the path will not factor. diff --git a/src/clj/com/rpl/specter.cljx b/src/clj/com/rpl/specter.cljx index 213b10f..756d127 100644 --- a/src/clj/com/rpl/specter.cljx +++ b/src/clj/com/rpl/specter.cljx @@ -363,30 +363,34 @@ will be parameterized in the order of which the parameterized navigators were declared." [& path] - (fixed-pathed-nav [late path] - (select* [this structure next-fn] - (i/filter-select - #(i/selected?* late %) - structure - next-fn)) - (transform* [this structure next-fn] - (i/filter-transform - #(i/selected?* late %) - structure - next-fn)))) + (if-let [afn (i/extract-basic-filter-fn path)] + afn + (fixed-pathed-nav [late path] + (select* [this structure next-fn] + (i/filter-select + #(i/selected?* late %) + structure + next-fn)) + (transform* [this structure next-fn] + (i/filter-transform + #(i/selected?* late %) + structure + next-fn))))) (defpathedfn not-selected? [& path] - (fixed-pathed-nav [late path] - (select* [this structure next-fn] - (i/filter-select - #(i/not-selected?* late %) - structure - next-fn)) - (transform* [this structure next-fn] - (i/filter-transform - #(i/not-selected?* late %) - structure - next-fn)))) + (if-let [afn (i/extract-basic-filter-fn path)] + (fn [s] (not (afn s))) + (fixed-pathed-nav [late path] + (select* [this structure next-fn] + (i/filter-select + #(i/not-selected?* late %) + structure + next-fn)) + (transform* [this structure next-fn] + (i/filter-transform + #(i/not-selected?* late %) + structure + next-fn))))) (defpathedfn filterer "Navigates to a view of the current sequence that only contains elements that diff --git a/test/com/rpl/specter/core_test.cljx b/test/com/rpl/specter/core_test.cljx index bbe6ae4..cf0fbb1 100644 --- a/test/com/rpl/specter/core_test.cljx +++ b/test/com/rpl/specter/core_test.cljx @@ -284,7 +284,10 @@ (setval [s/ALL (s/selected? s/ALL even?) s/END] [:a] [[1 3 5] [2] [7 11 4 2] [10 1] []] - )))) + ))) + (is (= [2 4] (select [s/ALL (s/selected? even?)] [1 2 3 4]))) + (is (= [1 3] (select [s/ALL (s/not-selected? even?)] [1 2 3 4]))) + ) (defspec identity-test (for-all+