diff options
author | Rich Hickey <richhickey@gmail.com> | 2010-04-28 17:17:56 -0400 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2010-04-28 17:17:56 -0400 |
commit | 9b78d483959e912a2ef77ff649b893b035144549 (patch) | |
tree | 8ab2ac00c2fabdbb27dddc40e63a8dc1ca190472 | |
parent | fab49c61d0b383d00270684a40bdf19bb2313ca6 (diff) |
tuned up into, added map-indexed, keep, keep-indexed
-rw-r--r-- | src/clj/clojure/core.clj | 72 |
1 files changed, 64 insertions, 8 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index 7721898f..00371db0 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -4995,14 +4995,8 @@ from-coll conjoined." [to from] (if (instance? clojure.lang.IEditableCollection to) - (#(loop [ret (transient to) items (seq from)] - (if items - (recur (conj! ret (first items)) (next items)) - (persistent! ret)))) - (#(loop [ret to items (seq from)] - (if items - (recur (conj ret (first items)) (next items)) - ret))))) + (persistent! (reduce conj! (transient to) from)) + (reduce conj to from))) (defn flatten "Takes any nested combination of sequential things (lists, vectors, @@ -5089,3 +5083,65 @@ (java.util.Collections/shuffle al) (clojure.lang.RT/vector (.toArray al)))) +(defn map-indexed + "Returns a lazy sequence consisting of the result of applying f to 0 + and the first item of coll, followed by applying f to 1 and the second + item in coll, etc, until coll is exhausted. Thus function f should + accept 2 arguments, index and item." + [f coll] + (letfn [(mapi [idx coll] + (lazy-seq + (when-let [s (seq coll)] + (if (chunked-seq? s) + (let [c (chunk-first s) + size (int (count c)) + b (chunk-buffer size)] + (dotimes [i size] + (chunk-append b (f (+ idx i) (.nth c i)))) + (chunk-cons (chunk b) (mapi (+ idx size) (chunk-rest s)))) + (cons (f idx (first s)) (mapi (inc idx) (rest s)))))))] + (mapi 0 coll))) + +(defn keep + "Returns a lazy sequence of the non-nil results of (f item). Note, + this means false return values will be included. f must be free of + side-effects." + ([f 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 (.nth c i))] + (when-not (nil? x) + (chunk-append b x)))) + (chunk-cons (chunk b) (keep f (chunk-rest s)))) + (let [x (f (first s))] + (if (nil? x) + (keep f (rest s)) + (cons x (keep f (rest s)))))))))) + +(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." + ([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 f (inc idx) (rest s)) + (cons x (keepi f (rest s)))))))))] + (keepi 0 coll)))) |