diff --git a/CHANGES.md b/CHANGES.md index 9d3ca57..fbf4f24 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,7 @@ +## 1.0.4-SNAPSHOT + +* Bug fix: Fix `INDEXED-VALS` invalidly overwriting elements in some transforms involving multiple index changes + ## 1.0.3 * Added `before-index` navigator for inserting a single element into a sequence. diff --git a/src/clj/com/rpl/specter.cljc b/src/clj/com/rpl/specter.cljc index f19604d..c9f5feb 100644 --- a/src/clj/com/rpl/specter.cljc +++ b/src/clj/com/rpl/specter.cljc @@ -1008,23 +1008,19 @@ (next-fn [(i/get-cell i) e]) ))) (transform* [this structure next-fn] - (let [i (i/mutable-cell 0) - indices (i/mutable-cell (-> structure count range vec))] + (let [indices (i/mutable-cell (-> structure count range))] (reduce (fn [s e] - (let [curri (nth (i/get-cell indices) (i/get-cell i)) + (let [curri (first (i/get-cell indices)) [newi newe] (next-fn [curri e])] - (if (> newi curri) - (i/update-cell! indices - (fn [ii] - (loop [j (inc curri) - s ii] - (let [news (update s j dec)] - (if (< j newi) - (recur (inc j) news) - news - )))))) - (i/update-cell! i inc) + (i/update-cell! + indices + (fn [ii] + (let [ii2 (next ii)] + (if (> newi curri) + (transform [ALL #(>= % (inc curri)) #(<= % newi)] dec ii2) + ii2 + )))) (->> s (setval (nthpath curri) newe) (setval (index-nav curri) newi) diff --git a/test/com/rpl/specter/core_test.cljc b/test/com/rpl/specter/core_test.cljc index 7a253dc..eab7f1a 100644 --- a/test/com/rpl/specter/core_test.cljc +++ b/test/com/rpl/specter/core_test.cljc @@ -1624,6 +1624,8 @@ (is (= [:a :b :e :d :c] (setval [s/INDEXED-VALS s/FIRST] 2 data))) (is (= [:b :a :d :c :e] (transform [s/INDEXED-VALS s/FIRST odd?] dec data))) (is (= [:a :b :c :d :e] (transform [s/INDEXED-VALS s/FIRST odd?] inc data))) + (is (= [0 2 2 4] (transform [s/INDEXED-VALS s/LAST odd?] inc [0 1 2 3]))) + (is (= [0 1 2 3] (transform [s/INDEXED-VALS (s/collect-one s/LAST) s/FIRST] (fn [i _] i) [2 1 3 0]))) )) #?(:clj