🐛 Fix index-of-pred early termination on nil elements

The index-of-pred function used (nil? c) to detect end-of-collection,
which caused premature termination when the collection contained nil
values. Rewrite using (seq coll) / (next s) pattern to correctly
distinguish between nil elements and end-of-sequence.
This commit is contained in:
Andrey Antukh 2026-04-14 20:05:35 +00:00 committed by Belén Albeza
parent 057c6ddc0d
commit 92dd5d9954
2 changed files with 13 additions and 9 deletions

View File

@ -291,15 +291,12 @@
(defn index-of-pred (defn index-of-pred
[coll pred] [coll pred]
(loop [c (first coll) (loop [s (seq coll)
coll (rest coll)
index 0] index 0]
(if (nil? c) (when s
nil (if (pred (first s))
(if (pred c)
index index
(recur (first coll) (recur (next s)
(rest coll)
(inc index)))))) (inc index))))))
(defn index-of (defn index-of

View File

@ -372,12 +372,19 @@
(t/is (= 0 (d/index-of-pred [1 2 3] odd?))) (t/is (= 0 (d/index-of-pred [1 2 3] odd?)))
(t/is (= 1 (d/index-of-pred [2 3 4] odd?))) (t/is (= 1 (d/index-of-pred [2 3 4] odd?)))
(t/is (nil? (d/index-of-pred [2 4 6] odd?))) (t/is (nil? (d/index-of-pred [2 4 6] odd?)))
(t/is (nil? (d/index-of-pred [] odd?)))) (t/is (nil? (d/index-of-pred [] odd?)))
;; works correctly when collection contains nil elements
(t/is (= 2 (d/index-of-pred [nil nil 3] some?)))
(t/is (= 0 (d/index-of-pred [nil 1 2] nil?)))
;; works correctly when collection contains false elements
(t/is (= 1 (d/index-of-pred [false true false] true?))))
(t/deftest index-of-test (t/deftest index-of-test
(t/is (= 0 (d/index-of [:a :b :c] :a))) (t/is (= 0 (d/index-of [:a :b :c] :a)))
(t/is (= 2 (d/index-of [:a :b :c] :c))) (t/is (= 2 (d/index-of [:a :b :c] :c)))
(t/is (nil? (d/index-of [:a :b :c] :z)))) (t/is (nil? (d/index-of [:a :b :c] :z)))
;; works when searching for nil in a collection
(t/is (= 1 (d/index-of [:a nil :c] nil))))
(t/deftest replace-by-id-test (t/deftest replace-by-id-test
(let [items [{:id 1 :v "a"} {:id 2 :v "b"} {:id 3 :v "c"}] (let [items [{:id 1 :v "a"} {:id 2 :v "b"} {:id 3 :v "c"}]