diff --git a/CHANGES.md b/CHANGES.md index 0f3e790..f8de6ff 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,6 @@ ## 1.0.1-SNAPSHOT +* `subselect`/`filterer` can remove entries in source by transforming to a smaller sequence * Add `satisfies-protpath?` * Inline cache vars are marked private so as not to interfere with tooling * Improve performance of `ALL` transform on lists by 20% diff --git a/src/clj/com/rpl/specter.cljc b/src/clj/com/rpl/specter.cljc index c258b34..b69632a 100644 --- a/src/clj/com/rpl/specter.cljc +++ b/src/clj/com/rpl/specter.cljc @@ -847,7 +847,10 @@ Requires that the input navigators will walk the structure's children in the same order when executed on \"select\" and then - \"transform\"." + \"transform\". + + If transformed sequence is smaller than input sequence, missing entries + will be filled in with NONE, triggering removal if supported by that navigator." [& path] (late-bound-nav [late (late-path path)] (select* [this structure next-fn] @@ -857,9 +860,12 @@ transformed (next-fn select-result) values-to-insert (i/mutable-cell transformed)] (compiled-transform late - (fn [_] (let [next-val (first (i/get-cell values-to-insert))] - (i/update-cell! values-to-insert rest) - next-val)) + (fn [_] (let [vs (i/get-cell values-to-insert)] + (if vs + (do (i/update-cell! values-to-insert next) + (first vs)) + NONE + ))) structure))))) (def ^{:doc "Navigate to the specified keys one after another. If navigate to NONE, @@ -952,7 +958,10 @@ (defdynamicnav filterer "Navigates to a view of the current sequence that only contains elements that match the given path. An element matches the selector path if calling select - on that element with the path yields anything other than an empty sequence." + on that element with the path yields anything other than an empty sequence. + + If transformed sequence is smaller than input sequence, the corresponding entries + will be removed from original sequence." [& path] (subselect ALL (selected? path))) diff --git a/test/com/rpl/specter/core_test.cljc b/test/com/rpl/specter/core_test.cljc index 023a4b7..44b3887 100644 --- a/test/com/rpl/specter/core_test.cljc +++ b/test/com/rpl/specter/core_test.cljc @@ -1514,6 +1514,10 @@ (is (= [10] (foo 10))) )) +(deftest filterer-remove-test + (is (= [1 :a 3 5] (setval (s/filterer even?) [:a] [1 2 3 4 5]))) + ) + #?(:clj (do (defprotocolpath FooPP)