ClojureDocs

导航

命名空间

分区

clojure.core

1.0 起可用 (来源)
  • (partition n coll)
  • (partition n step coll)
  • (partition n step pad coll)
Returns a lazy sequence of lists of n items each, at offsets step
apart. If step is not supplied, defaults to n, i.e. the partitions
do not overlap. If a pad collection is supplied, use its elements as
necessary to complete last partition upto n items. In case there are
not enough padding elements, return a partition with less than n items.
9 Examples
;; partition a list of 20 items into 5 (20/4) lists of 4 items
(partition 4 (range 20))
;;=> ((0 1 2 3) (4 5 6 7) (8 9 10 11) (12 13 14 15) (16 17 18 19))

;; partition a list of 22 items into 5 (20/4) lists of 4 items 
;; the last two items do not make a complete partition and are dropped.
(partition 4 (range 22))
;;=> ((0 1 2 3) (4 5 6 7) (8 9 10 11) (12 13 14 15) (16 17 18 19))

;; uses the step to select the starting point for each partition
(partition 4 6 (range 20))
;;=> ((0 1 2 3) (6 7 8 9) (12 13 14 15))

;; if the step is smaller than the partition size, items will be reused
(partition 4 3 (range 20))
;;=> ((0 1 2 3) (3 4 5 6) (6 7 8 9) (9 10 11 12) (12 13 14 15) (15 16 17 18))

;; when there are not enough items to fill the last partition, a pad can be supplied.
(partition 3 6 ["a"] (range 20))
;;=> ((0 1 2) (6 7 8) (12 13 14) (18 19 "a"))

;; when a pad is supplied, the last partition may not be of the same size as the rest
(partition 4 6 ["a"] (range 20))
;;=> ((0 1 2 3) (6 7 8 9) (12 13 14 15) (18 19 "a"))

;; but only as many pad elements are used as necessary to fill the final partition.
(partition 4 6 ["a" "b" "c" "d"] (range 20))
;;=> ((0 1 2 3) (6 7 8 9) (12 13 14 15) (18 19 "a" "b"))
;; a step smaller than the partition-size results in reuse.
(partition 3 1 [:a :b :c :d :e :f])
;;=> ((:a :b :c) (:b :c :d) (:c :d :e) (:d :e :f))
;; When there are less than n items in the coll, partition's behaviour
;; depends on whether there is a pad or not

;; without pad
(partition 10 [1 2 3 4])
;;=> ()

;; again, without pad
(partition 10 10 [1 2 3 4])
;;=> ()

;; with a pad this time (note: the pad is an empty sequence)
(partition 10 10 nil [1 2 3 4])
;;=> ((1 2 3 4))

;; or, explicit empty sequence instead of nil
(partition 10 10 [] [1 2 3 4])
;;=> ((1 2 3 4))
;; Partitioning 0 elements will produce an infinite seq of empty sequences
(partition 0 [1 2 3])
;; *hangs*

(take 5 (partition 0 [1 2 3]))
;; => (() () () () ())
;; Using nil as a pad will let the incomplete partition in the result
;; Here we use it to drop every fourth element in an array
(partition 3 4 nil [1 2 3 4 5 6 7 8 9])
;;((1 2 3) (5 6 7) (9))
;; Here is a nice little trick to make a ring.
(def foo [5 6 7 8])

(partition 2 1 foo foo)
;;=> ((5 6) (6 7) (7 8) (8 5))

;; This will produce a part for each element of foo.
;; Without the pad stops sooner.
(partition 2 1 foo)
;;=> ((5 6) (6 7) (7 8))

;; Just how crazy can this get?
(partition 4 1 foo foo)
;;=> ((5 6 7 8) (6 7 8 5))
;; Not too crazy, this illustrates the 
;; fact that the first use of the pad halts the partitioning.
;; To my way of thinking this is not what I expected.

;; The following alternative implementation continues 
;; until the coll has been consumed once completely.
(defn spiral
  ([n step coll]
   (spiral n step coll coll))
  ([n step pad coll]
   (lazy-seq
     (when-let [s (seq coll)]
       (let [p (doall (take n s))
             item (take n (apply concat p (repeat pad)))]
         (if (< 1 (count p))
           (cons item (spiral n step pad (nthrest s step)))
           (list item)))))))
(spiral 4 1 foo)
;;=> ((5 6 7 8) (6 7 8 5) (7 8 5 6) (8 5 6 7))

(spiral 4 2 foo)
;;=> ((5 6 7 8) (7 8 5 6))

(spiral 6 1 foo)
;;=> ((5 6 7 8 5 6) (6 7 8 5 6 7) (7 8 5 6 7 8) (8 5 6 7 8 5))

(def bar [:a :b :c])
(spiral 6 2 bar foo)
;;=> ((5 6 7 8 :a :b) (7 8 :a :b :c :a))

;; Note that if you don’t need the padding, the function above can be
;; simplified a lot by using cycle:
(defn spiral
  [n offset coll]
  (take (/ (count coll) offset) (partition n offset (cycle coll))))
;; In case you want behaviour similar to Ruby's each_slice, 
;; where the last sequence doesn't necessarily have the same 
;; size as the others, you can just provide an empty or nil pad value.
(partition 3 3 nil (range 11))
;;=> ((0 1 2) (3 4 5) (6 7 8) (9 10)))

;; This is the default behavior of partition-all
(partition-all 3 3 (range 11))
;;=> ((0 1 2) (3 4 5) (6 7 8) (9 10))) 
user=> (partition 5 "superfragilistic")
((\s \u \p \e \r) (\f \r \a \g \i) (\l \i \s \t \i))
;; There's no transducer arity for partition, but there is for partition-all
;; To enforce full partitions only, we can provide our own reducing function…
(let [rf (completing (fn [acc x] (cond-> acc (= 3 (count x)) (conj x))))]
  (transduce (partition-all 3) rf [] '[a b c d e f g]))
;; => [[a b c] [d e f]]

;; Or we can add a take-while transducer…
(into [] (comp (partition-all 3) (take-while #(= 3 (count %)))) '[a b c d e f g])
;; => [[a b c] [d e f]]
See Also

Returns a lazy sequence of lists like partition, but may include partitions with fewer than n item...

Added by TimMc

Returns a vector of [(take n coll) (drop n coll)]

Added by Havvy

Applies f to each value in coll, splitting it each time f returns a new value. Returns a lazy se...

Added by rjack

Returns a lazy (infinite!) sequence of repetitions of the items in coll.

Added by bfontaine
0 Notes
No notes for partition