Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 239 lines (206 sloc) 7.982 kB
04eb37e @scgilardi minimal port to Clojure SVN 1094+ of seq-utils import-static trace en…
scgilardi authored
1 ;;; seq_utils.clj -- Sequence utilities for Clojure
2
3 ;; by Stuart Sierra, http://stuartsierra.com/
3fd57b7 seq-utils: new multimethod seq-on
Konrad Hinsen authored
4 ;; last updated March 2, 2009
04eb37e @scgilardi minimal port to Clojure SVN 1094+ of seq-utils import-static trace en…
scgilardi authored
5
7cfb20f @stuartsierra Stuart Sierra: Moved libs I wrote to Eclipse Public License 1.0
stuartsierra authored
6 ;; Copyright (c) Stuart Sierra, 2008. All rights reserved. The use
7 ;; and distribution terms for this software are covered by the Eclipse
8 ;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
9 ;; which can be found in the file epl-v10.html at the root of this
04eb37e @scgilardi minimal port to Clojure SVN 1094+ of seq-utils import-static trace en…
scgilardi authored
10 ;; distribution. By using this software in any fashion, you are
11 ;; agreeing to be bound by the terms of this license. You must not
12 ;; remove this notice, or any other, from this software.
13
14
7240a2a @stuartsierra seq_utils.clj: BREAKING CHANGE: swap argument order of "includes?"
stuartsierra authored
15 ;; Change Log
16 ;;
17 ;; January 10, 2009 (Stuart Sierra):
18 ;;
19 ;; * BREAKING CHANGE: "includes?" now takes collection as first
20 ;; argument. This is more consistent with Clojure collection
21 ;; functions; see discussion at http://groups.google.com/group/clojure/browse_thread/thread/8b2c8dc96b39ddd7/a8866d34b601ff43
22
95dddbb @stuarthalloway keep deprecated version of seq fns, safe(r) now that we have "last va…
stuarthalloway authored
23
86e9001 @tomfaulhaber Lots 'o doc strings
tomfaulhaber authored
24 (ns
b8d2743 use the 1.2 metadata reader macro ^ instead of #^
Aaron Bedra and Stuart Halloway authored
25 ^{:author "Stuart Sierra (and others)",
86e9001 @tomfaulhaber Lots 'o doc strings
tomfaulhaber authored
26 :doc "Sequence utilities for Clojure"}
ec6a757 @stuartsierra Change ns names for all renamed libs except str-utils
stuartsierra authored
27 clojure.contrib.seq
2d2c200 @Chouser seq-utils: Add fill-queue
Chouser authored
28 (:import (java.util.concurrent LinkedBlockingQueue TimeUnit)
95dddbb @stuarthalloway keep deprecated version of seq fns, safe(r) now that we have "last va…
stuarthalloway authored
29 (java.lang.ref WeakReference))
30 (:refer-clojure :exclude [frequencies shuffle partition-by reductions partition-all group-by flatten]))
31
32
33 ;; 'flatten' written by Rich Hickey,
34 ;; see http://groups.google.com/group/clojure/msg/385098fabfcaad9b
35 (defn flatten
36 "DEPRECATED. Prefer clojure.core version.
37 Takes any nested combination of sequential things (lists, vectors,
38 etc.) and returns their contents as a single, flat sequence.
39 (flatten nil) returns nil."
40 {:deprecated "1.2"}
41 [x]
42 (filter (complement sequential?)
43 (rest (tree-seq sequential? seq x))))
04eb37e @scgilardi minimal port to Clojure SVN 1094+ of seq-utils import-static trace en…
scgilardi authored
44
45 (defn separate
46 "Returns a vector:
47 [ (filter f s), (filter (complement f) s) ]"
48 [f s]
49 [(filter f s) (filter (complement f) s)])
50
51 (defn indexed
52 "Returns a lazy sequence of [index, item] pairs, where items come
53 from 's' and indexes count up from zero.
54
55 (indexed '(a b c d)) => ([0 a] [1 b] [2 c] [3 d])"
56 [s]
57 (map vector (iterate inc 0) s))
58
95dddbb @stuarthalloway keep deprecated version of seq fns, safe(r) now that we have "last va…
stuarthalloway authored
59 ;; group-by written by Rich Hickey;
60 ;; see http://paste.lisp.org/display/64190
61 (defn group-by
62 "DEPRECATED. Prefer clojure.core version.
63 Returns a sorted map of the elements of coll keyed by the result of
64 f on each element. The value at each key will be a vector of the
65 corresponding elements, in the order they appeared in coll."
66 {:deprecated "1.2"}
67 [f coll]
68 (reduce
69 (fn [ret x]
70 (let [k (f x)]
71 (assoc ret k (conj (get ret k []) x))))
72 (sorted-map) coll))
73
74 ;; partition-by originally written by Rich Hickey;
75 ;; modified by Stuart Sierra
76 (defn partition-by
77 "DEPRECATED. Prefer clojure.core version.
78 Applies f to each value in coll, splitting it each time f returns
79 a new value. Returns a lazy seq of lazy seqs."
80 {:deprecated "1.2"}
81 [f coll]
82 (when-let [s (seq coll)]
83 (let [fst (first s)
84 fv (f fst)
85 run (cons fst (take-while #(= fv (f %)) (rest s)))]
86 (lazy-seq
87 (cons run (partition-by f (drop (count run) s)))))))
88
89 (defn frequencies
90 "DEPRECATED. Prefer clojure.core version.
91 Returns a map from distinct items in coll to the number of times
92 they appear."
93 {:deprecated "1.2"}
94 [coll]
95 (reduce (fn [counts x]
96 (assoc counts x (inc (get counts x 0))))
97 {} coll))
98
422ec0a @cgrand added rec-cat, rec-cons and reductions
cgrand authored
99 ;; recursive sequence helpers by Christophe Grand
100 ;; see http://clj-me.blogspot.com/2009/01/recursive-seqs.html
0cb2904 @cgrand replaced rec-cons by rec-seq
cgrand authored
101 (defmacro rec-seq
102 "Similar to lazy-seq but binds the resulting seq to the supplied
103 binding-name, allowing for recursive expressions."
104 [binding-name & body]
188682d @cgrand back to a mutation-based rec-seq
cgrand authored
105 `(let [s# (atom nil)]
38e603d @cgrand I keep forgetting the existence of reset!
cgrand authored
106 (reset! s# (lazy-seq (let [~binding-name @s#] ~@body)))))
188682d @cgrand back to a mutation-based rec-seq
cgrand authored
107
422ec0a @cgrand added rec-cat, rec-cons and reductions
cgrand authored
108 (defmacro rec-cat
0cb2904 @cgrand replaced rec-cons by rec-seq
cgrand authored
109 "Similar to lazy-cat but binds the resulting sequence to the supplied
110 binding-name, allowing for recursive expressions."
111 [binding-name & exprs]
112 `(rec-seq ~binding-name (lazy-cat ~@exprs)))
422ec0a @cgrand added rec-cat, rec-cons and reductions
cgrand authored
113
95dddbb @stuarthalloway keep deprecated version of seq fns, safe(r) now that we have "last va…
stuarthalloway authored
114
115 ;; reductions by Chris Houser
116 ;; see http://groups.google.com/group/clojure/browse_thread/thread/3edf6e82617e18e0/58d9e319ad92aa5f?#58d9e319ad92aa5f
117 (defn reductions
118 "DEPRECATED. Prefer clojure.core version.
119 Returns a lazy seq of the intermediate values of the reduction (as
120 per reduce) of coll by f, starting with init."
121 {:deprecated "1.2"}
122 ([f coll]
123 (if (seq coll)
124 (rec-seq self (cons (first coll) (map f self (rest coll))))
125 (cons (f) nil)))
126 ([f init coll]
127 (rec-seq self (cons init (map f self coll)))))
128
f4bc200 @scgilardi fix issue 29: move sequence functions from lazy_seqs to seq_utils
scgilardi authored
129 (defn rotations
130 "Returns a lazy seq of all rotations of a seq"
131 [x]
132 (if (seq x)
133 (map
134 (fn [n _]
135 (lazy-cat (drop n x) (take n x)))
136 (iterate inc 0) x)
137 (list nil)))
138
95dddbb @stuarthalloway keep deprecated version of seq fns, safe(r) now that we have "last va…
stuarthalloway authored
139 (defn partition-all
140 "DEPRECATED. Prefer clojure.core version.
141 Returns a lazy sequence of lists like clojure.core/partition, but may
142 include lists with fewer than n items at the end."
143 {:deprecated "1.2"}
144 ([n coll]
145 (partition-all n n coll))
146 ([n step coll]
147 (lazy-seq
148 (when-let [s (seq coll)]
149 (cons (take n s) (partition-all n step (drop step s)))))))
150
151 (defn shuffle
152 "DEPRECATED. Prefer clojure.core version.
153 Return a random permutation of coll"
154 {:deprecated "1.2"}
155 [coll]
156 (let [l (java.util.ArrayList. coll)]
157 (java.util.Collections/shuffle l)
158 (seq l)))
159
160 (defn rand-elt
161 "DEPRECATED. Prefer clojure.core/rand-nth.
162 Return a random element of this seq"
163 {:deprecated "1.2"}
164 [s]
165 (nth s (rand-int (count s))))
166
86e9001 @tomfaulhaber Lots 'o doc strings
tomfaulhaber authored
167 ;; seq-on written by Konrad Hinsen
3fd57b7 seq-utils: new multimethod seq-on
Konrad Hinsen authored
168 (defmulti seq-on
169 "Returns a seq on the object s. Works like the built-in seq but as
170 a multimethod that can have implementations for new classes and types."
171 {:arglists '([s])}
172 type)
173
174 (defmethod seq-on :default
175 [s]
176 (seq s))
0c92dbf @stuartsierra seq_utils.clj: added "seek" function, for (first (filter ...))
stuartsierra authored
177
178
8322249 @stuartsierra seq_utils.clj: renamed "seek" to "find-first"
stuartsierra authored
179 (defn find-first
0c92dbf @stuartsierra seq_utils.clj: added "seek" function, for (first (filter ...))
stuartsierra authored
180 "Returns the first item of coll for which (pred item) returns logical true.
181 Consumes sequences up to the first match, will consume the entire sequence
182 and return nil if no match is found."
183 [pred coll]
184 (first (filter pred coll)))
2d2c200 @Chouser seq-utils: Add fill-queue
Chouser authored
185
da640a5 @Chouser seq-utils: Fix fill-queue attribution
Chouser authored
186 ; based on work related to Rich Hickey's seque.
187 ; blame Chouser for anything broken or ugly.
2d2c200 @Chouser seq-utils: Add fill-queue
Chouser authored
188 (defn fill-queue
189 "filler-func will be called in another thread with a single arg
190 'fill'. filler-func may call fill repeatedly with one arg each
191 time which will be pushed onto a queue, blocking if needed until
192 this is possible. fill-queue will return a lazy seq of the values
193 filler-func has pushed onto the queue, blocking if needed until each
194 next element becomes available. filler-func's return value is ignored."
195 ([filler-func & optseq]
196 (let [opts (apply array-map optseq)
197 apoll (:alive-poll opts 1)
198 q (LinkedBlockingQueue. (:queue-size opts 1))
199 NIL (Object.) ;nil sentinel since LBQ doesn't support nils
200 weak-target (Object.)
201 alive? (WeakReference. weak-target)
202 fill (fn fill [x]
203 (if (.get alive?)
204 (if (.offer q (if (nil? x) NIL x) apoll TimeUnit/SECONDS)
205 x
206 (recur x))
207 (throw (Exception. "abandoned"))))
208 f (future
209 (try
210 (filler-func fill)
211 (finally
212 (.put q q))) ;q itself is eos sentinel
213 nil)] ; set future's value to nil
214 ((fn drain []
215 weak-target ; force closing over this object
216 (lazy-seq
217 (let [x (.take q)]
218 (if (identical? x q)
219 @f ;will be nil, touch just to propagate errors
220 (cons (if (identical? x NIL) nil x)
221 (drain))))))))))
222
1640c04 positions takes only a predicate, per Rich's feedback
Aaron Bedra and Stuart Halloway authored
223 (defn positions
224 "Returns a lazy sequence containing the positions at which pred
225 is true for items in coll."
226 [pred coll]
b70cba0 add seq-utils/positions
Aaron Bedra and Stuart Halloway authored
227 (for [[idx elt] (indexed coll) :when (pred elt)] idx))
228
48b81e0 @stuarthalloway put includes? back into the seq namespaces
stuarthalloway authored
229 (defn includes?
230 "Returns true if coll contains something equal (with =) to x,
95dddbb @stuarthalloway keep deprecated version of seq fns, safe(r) now that we have "last va…
stuarthalloway authored
231 in linear time. Deprecated. Prefer 'contains?' for key testing,
48b81e0 @stuarthalloway put includes? back into the seq namespaces
stuarthalloway authored
232 or 'some' for ad hoc linear searches."
95dddbb @stuarthalloway keep deprecated version of seq fns, safe(r) now that we have "last va…
stuarthalloway authored
233 {:deprecated "1.2"}
48b81e0 @stuarthalloway put includes? back into the seq namespaces
stuarthalloway authored
234 [coll x]
235 (boolean (some (fn [y] (= y x)) coll)))
b70cba0 add seq-utils/positions
Aaron Bedra and Stuart Halloway authored
236
237
238
Something went wrong with that request. Please try again.