886
886
(-iterator [coll]
887
887
" Returns an iterator for coll." ))
888
888
889
+ (defprotocol IDrop
890
+ " Protocol for persistent or algorithmically defined collections to provide a
891
+ means of dropping N items that is more efficient than sequential walking."
892
+ (^clj-or-nil -drop [coll n]
893
+ " Returns a collection that is ISequential, ISeq, and IReduce, or nil if past
894
+ the end. The number of items to drop n must be > 0. It is also useful if the
895
+ returned coll implements IDrop for subsequent use in a partition-like scenario." ))
896
+
889
897
; ; Printing support
890
898
891
899
(deftype StringBufferWriter [sb]
@@ -1631,6 +1639,14 @@ reduces them without incurring seq initialization"
1631
1639
(IndexedSeq. arr (inc i) nil )
1632
1640
nil ))
1633
1641
1642
+ IDrop
1643
+ (-drop [coll n]
1644
+ (if (pos? n)
1645
+ (if (< (+ i n) (alength arr))
1646
+ (IndexedSeq. arr (+ i n) nil )
1647
+ nil )
1648
+ coll))
1649
+
1634
1650
ICounted
1635
1651
(-count [_]
1636
1652
(max 0 (- (alength arr) i)))
@@ -1949,10 +1965,14 @@ reduces them without incurring seq initialization"
1949
1965
(defn nthrest
1950
1966
" Returns the nth rest of coll, coll when n is 0."
1951
1967
[coll n]
1952
- (loop [n n xs coll]
1953
- (if-let [xs (and (pos? n) (seq xs))]
1954
- (recur (dec n) (rest xs))
1955
- xs)))
1968
+ (if (implements? IDrop coll)
1969
+ (if (pos? n)
1970
+ (or (-drop coll (Math/ceil n)) ())
1971
+ coll)
1972
+ (loop [n n xs coll]
1973
+ (if-let [xs (and (pos? n) (seq xs))]
1974
+ (recur (dec n) (rest xs))
1975
+ xs))))
1956
1976
1957
1977
(defn get
1958
1978
" Returns the value mapped to key, not-found or nil if key not present
@@ -2997,10 +3017,14 @@ reduces them without incurring seq initialization"
2997
3017
(defn nthnext
2998
3018
" Returns the nth next of coll, (seq coll) when n is 0."
2999
3019
[coll n]
3000
- (loop [n n xs (seq coll)]
3001
- (if (and xs (pos? n))
3002
- (recur (dec n) (next xs))
3003
- xs)))
3020
+ (if (implements? IDrop coll)
3021
+ (if (pos? n)
3022
+ (-drop coll (Math/ceil n))
3023
+ (seq coll))
3024
+ (loop [n n xs (seq coll)]
3025
+ (if (and xs (pos? n))
3026
+ (recur (dec n) (next xs))
3027
+ xs))))
3004
3028
3005
3029
; ;;;;;;;;;;;;;;;;;;;;;;;;; basics ;;;;;;;;;;;;;;;;;;
3006
3030
@@ -4828,7 +4852,7 @@ reduces them without incurring seq initialization"
4828
4852
(cons (first s) (take (dec n) (rest s))))))))
4829
4853
4830
4854
(defn drop
4831
- " Returns a lazy sequence of all but the first n items in coll.
4855
+ " Returns a laziness-preserving sequence of all but the first n items in coll.
4832
4856
Returns a stateful transducer when no collection is provided."
4833
4857
([n]
4834
4858
{:pre [(number? n)]}
@@ -4845,12 +4869,18 @@ reduces them without incurring seq initialization"
4845
4869
(rf result input))))))))
4846
4870
([n coll]
4847
4871
{:pre [(number? n)]}
4848
- (let [step (fn [n coll]
4849
- (let [s (seq coll)]
4850
- (if (and (pos? n) s)
4851
- (recur (dec n) (rest s))
4852
- s)))]
4853
- (lazy-seq (step n coll)))))
4872
+ (if (implements? IDrop coll)
4873
+ (or
4874
+ (if (pos? n)
4875
+ (-drop coll (Math/ceil n))
4876
+ (seq coll))
4877
+ ())
4878
+ (let [step (fn [n coll]
4879
+ (let [s (seq coll)]
4880
+ (if (and (pos? n) s)
4881
+ (recur (dec n) (rest s))
4882
+ s)))]
4883
+ (lazy-seq (step n coll))))))
4854
4884
4855
4885
(defn drop-last
4856
4886
" Return a lazy sequence of all but the last n (default 1) items in coll"
@@ -5019,6 +5049,14 @@ reduces them without incurring seq initialization"
5019
5049
ICollection
5020
5050
(-conj [coll o] (cons o coll))
5021
5051
5052
+ IDrop
5053
+ (-drop [coll n]
5054
+ (if (== count -1 )
5055
+ coll
5056
+ (let [dropped-count (- count n)]
5057
+ (when (pos? dropped-count)
5058
+ (Repeat. nil dropped-count val nil nil )))))
5059
+
5022
5060
IEmptyableCollection
5023
5061
(-empty [coll] (.-EMPTY List))
5024
5062
@@ -5645,6 +5683,13 @@ reduces them without incurring seq initialization"
5645
5683
(<= cnt 32 ) (IndexedSeq. tail 0 nil )
5646
5684
:else (chunked-seq coll (first-array-for-longvec coll) 0 0 )))
5647
5685
5686
+ IDrop
5687
+ (-drop [coll n]
5688
+ (if (< n cnt)
5689
+ (let [offset (js-mod n 32 )]
5690
+ (chunked-seq coll (unchecked-array-for coll n) (- n offset) offset))
5691
+ nil ))
5692
+
5648
5693
ICounted
5649
5694
(-count [coll] cnt)
5650
5695
@@ -5849,6 +5894,17 @@ reduces them without incurring seq initialization"
5849
5894
s))
5850
5895
(-chunked-next coll)))
5851
5896
5897
+ IDrop
5898
+ (-drop [coll n]
5899
+ (let [o (+ off n)]
5900
+ (if (< o (alength node))
5901
+ (chunked-seq vec node i o)
5902
+ (let [i (+ i o)]
5903
+ (if (< i (-count vec))
5904
+ (let [new-offset (js-mod i 32 )]
5905
+ (chunked-seq vec (unchecked-array-for vec i) (- i new-offset) new-offset))
5906
+ nil )))))
5907
+
5852
5908
ICollection
5853
5909
(-conj [coll o]
5854
5910
(cons o coll))
@@ -6864,6 +6920,11 @@ reduces them without incurring seq initialization"
6864
6920
(when (< i (- (alength arr) 2 ))
6865
6921
(PersistentArrayMapSeq. arr (+ i 2 ) nil )))
6866
6922
6923
+ IDrop
6924
+ (-drop [coll n]
6925
+ (when (< n (-count coll))
6926
+ (PersistentArrayMapSeq. arr (+ i (* 2 n)) nil )))
6927
+
6867
6928
IReduce
6868
6929
(-reduce [coll f] (seq-reduce f coll))
6869
6930
(-reduce [coll f start] (seq-reduce f start coll)))
@@ -6964,6 +7025,11 @@ reduces them without incurring seq initialization"
6964
7025
(-seq [coll]
6965
7026
(persistent-array-map-seq arr 0 nil ))
6966
7027
7028
+ IDrop
7029
+ (-drop [coll n]
7030
+ (when-some [s (-seq coll)]
7031
+ (-drop s n)))
7032
+
6967
7033
ICounted
6968
7034
(-count [coll] cnt)
6969
7035
@@ -9737,6 +9803,47 @@ reduces them without incurring seq initialization"
9737
9803
(when-let [s (seq coll)]
9738
9804
(cons (take n s) (partition-all n step (drop step s)))))))
9739
9805
9806
+ (defn splitv-at
9807
+ " Returns a vector of [(into [] (take n) coll) (drop n coll)]"
9808
+ [n coll]
9809
+ [(into [] (take n) coll) (drop n coll)])
9810
+
9811
+ (defn partitionv
9812
+ " Returns a lazy sequence of vectors of n items each, at offsets step
9813
+ apart. If step is not supplied, defaults to n, i.e. the partitions
9814
+ do not overlap. If a pad collection is supplied, use its elements as
9815
+ necessary to complete last partition upto n items. In case there are
9816
+ not enough padding elements, return a partition with less than n items."
9817
+ ([n coll]
9818
+ (partitionv n n coll))
9819
+ ([n step coll]
9820
+ (lazy-seq
9821
+ (when-let [s (seq coll)]
9822
+ (let [p (into [] (take n) s)]
9823
+ (when (= n (count p))
9824
+ (cons p (partitionv n step (nthrest s step))))))))
9825
+ ([n step pad coll]
9826
+ (lazy-seq
9827
+ (when-let [s (seq coll)]
9828
+ (let [p (into [] (take n) s)]
9829
+ (if (= n (count p))
9830
+ (cons p (partitionv n step pad (nthrest s step)))
9831
+ (list (into [] (take n) (concat p pad)))))))))
9832
+
9833
+ (defn partitionv-all
9834
+ " Returns a lazy sequence of vector partitions, but may include
9835
+ partitions with fewer than n items at the end.
9836
+ Returns a stateful transducer when no collection is provided."
9837
+ ([n]
9838
+ (partition-all n))
9839
+ ([n coll]
9840
+ (partitionv-all n n coll))
9841
+ ([n step coll]
9842
+ (lazy-seq
9843
+ (when-let [s (seq coll)]
9844
+ (let [seg (into [] (take n) coll)]
9845
+ (cons seg (partitionv-all n step (drop step s))))))))
9846
+
9740
9847
(defn take-while
9741
9848
" Returns a lazy sequence of successive items from coll while
9742
9849
(pred item) returns logical true. pred must be free of side-effects.
@@ -9824,7 +9931,12 @@ reduces them without incurring seq initialization"
9824
9931
(set! i (+ i step))
9825
9932
ret)))
9826
9933
9827
- (deftype IntegerRange [meta start end step ^:mutable chunk ^:mutable chunk-next ^:mutable __hash]
9934
+ (defn- range-count
9935
+ " Returns exact size of remaining items in an IntegerRange."
9936
+ [start end step]
9937
+ (Math/ceil (/ (- end start) step)))
9938
+
9939
+ (deftype IntegerRange [meta start end step cnt ^:mutable __hash]
9828
9940
Object
9829
9941
(toString [coll]
9830
9942
(pr-str* coll))
@@ -9838,23 +9950,15 @@ reduces them without incurring seq initialization"
9838
9950
(-lastIndexOf coll x (count coll)))
9839
9951
(lastIndexOf [coll x start]
9840
9952
(-lastIndexOf coll x start))
9841
- (forceChunk [coll]
9842
- (when (nil? chunk)
9843
- (let [count (-count coll)]
9844
- (if (> count 32 )
9845
- (do
9846
- (set! chunk-next (IntegerRange. nil (+ start (* step 32 )) end step nil nil nil ))
9847
- (set! chunk (IntegerRangeChunk. start step 32 )))
9848
- (set! chunk (IntegerRangeChunk. start step count))))))
9849
9953
9850
9954
ICloneable
9851
- (-clone [_] (IntegerRange. meta start end step chunk chunk-next __hash))
9955
+ (-clone [_] (IntegerRange. meta start end step cnt __hash))
9852
9956
9853
9957
IWithMeta
9854
9958
(-with-meta [rng new-meta]
9855
9959
(if (identical? new-meta meta)
9856
9960
rng
9857
- (IntegerRange. new-meta start end step chunk chunk-next __hash)))
9961
+ (IntegerRange. new-meta start end step cnt __hash)))
9858
9962
9859
9963
IMeta
9860
9964
(-meta [rng] meta)
@@ -9878,19 +9982,40 @@ reduces them without incurring seq initialization"
9878
9982
(-next [rng]
9879
9983
(if (pos? step)
9880
9984
(when (< (+ start step) end)
9881
- (IntegerRange. nil (+ start step) end step nil nil nil ))
9985
+ (IntegerRange. nil (+ start step) end step ( range-count ( + start step) end step) nil ))
9882
9986
(when (> (+ start step) end)
9883
- (IntegerRange. nil (+ start step) end step nil nil nil ))))
9987
+ (IntegerRange. nil (+ start step) end step (range-count (+ start step) end step) nil ))))
9988
+
9989
+ IDrop
9990
+ (-drop [rng n]
9991
+ (if (pos? n)
9992
+ (if (< n cnt)
9993
+ (IntegerRange. nil (+ start (* step n)) end step (- cnt n) nil )
9994
+ nil )
9995
+ rng))
9884
9996
9885
9997
IChunkedSeq
9886
9998
(-chunked-first [rng]
9887
- (.forceChunk rng)
9888
- chunk)
9999
+ (IntegerRangeChunk. start step (min cnt 32 )))
9889
10000
(-chunked-rest [rng]
9890
- (.forceChunk rng)
9891
- (if (nil? chunk-next)
10001
+ (if (<= cnt 32 )
9892
10002
()
9893
- chunk-next))
10003
+ (let [start (+ start (* step 32 ))]
10004
+ (cond
10005
+ (pos? step)
10006
+ (if (<= end start)
10007
+ ()
10008
+ (IntegerRange. nil start end step (range-count start end step) nil ))
10009
+
10010
+ (neg? step)
10011
+ (if (>= end start)
10012
+ ()
10013
+ (IntegerRange. nil start end step (range-count start end step) nil ))
10014
+
10015
+ :else
10016
+ (if (== end start)
10017
+ ()
10018
+ (repeat start))))))
9894
10019
9895
10020
IChunkedNext
9896
10021
(-chunked-next [rng]
@@ -9911,7 +10036,7 @@ reduces them without incurring seq initialization"
9911
10036
9912
10037
ICounted
9913
10038
(-count [rng]
9914
- ( Math/ceil ( / ( - end start) step)) )
10039
+ cnt )
9915
10040
9916
10041
IIndexed
9917
10042
(-nth [rng n]
@@ -10060,14 +10185,14 @@ reduces them without incurring seq initialization"
10060
10185
(if (<= end start)
10061
10186
()
10062
10187
(if (and (integer? start) (integer? end) (integer? step))
10063
- (IntegerRange. nil start end step nil nil nil )
10188
+ (IntegerRange. nil start end step ( range-count start end step) nil )
10064
10189
(Range. nil start end step nil nil nil )))
10065
10190
10066
10191
(neg? step)
10067
10192
(if (>= end start)
10068
10193
()
10069
10194
(if (and (integer? start) (integer? end) (integer? step))
10070
- (IntegerRange. nil start end step nil nil nil )
10195
+ (IntegerRange. nil start end step ( range-count start end step) nil )
10071
10196
(Range. nil start end step nil nil nil )))
10072
10197
10073
10198
:else
0 commit comments