Returns a lazy sequence of the non-nil results of (f index item). Note,
this means false return values will be included. f must be free of
side-effects.
user=> (keep-indexed #(if (pos? %2) %1) [-9 0 29 -7 45 3 -8])
(2 4 5)
;; f takes 2 args: 'index' and 'value' where index is 0-based
;; when f returns nil the index is not included in final result
user=> (keep-indexed (fn [idx v]
(if (pos? v) idx)) [-9 0 29 -7 45 3 -8])
(2 4 5)
(defn position [x coll & {:keys [from-end all] :or {from-end false all false}}]
(cond
(true? from-end) (last (keep-indexed #(if (= x %2) %1) coll))
(true? all) (keep-indexed #(if (= x %2) %1) coll)
:else (first (keep-indexed #(if (= x %2) %1) coll))))
user> (position [1 1] [[1 0][1 1][2 3][1 1]])
1
user> (position [1 1] [[1 0][1 1][2 3][1 1]] :from-end true)
3
user> (position [1 1] [[1 0][1 1][2 3][1 1]] :all true)
(1 3)
user> (def foo (shuffle (range 10)))
#'user/foo
user> foo
(5 8 9 1 2 7 0 6 3 4)
user> (position 5 foo)
0
user> (position 0 foo)
6
(defn keep-indexed
"Returns a lazy sequence of the non-nil results of (f index item). Note,
this means false return values will be included. f must be free of
side-effects."
{:added "1.2"
:static true}
([f coll]
(letfn [(keepi [idx coll]
(lazy-seq
(when-let [s (seq coll)]
(if (chunked-seq? s)
(let [c (chunk-first s)
size (count c)
b (chunk-buffer size)]
(dotimes [i size]
(let [x (f (+ idx i) (.nth c i))]
(when-not (nil? x)
(chunk-append b x))))
(chunk-cons (chunk b) (keepi (+ idx size) (chunk-rest s))))
(let [x (f idx (first s))]
(if (nil? x)
(keepi (inc idx) (rest s))
(cons x (keepi (inc idx) (rest s)))))))))]
(keepi 0 coll))))
Comments top
No comments for keep-indexed. Log in to add a comment.