(partition-by f) (partition-by f coll)
Applies f to each value in coll, splitting it each time f returns a new value. Returns a lazy seq of partitions. Returns a stateful transducer when no collection is provided.
user=> (partition-by #(= 3 %) [1 2 3 4 5])
((1 2) (3) (4 5))
user=> (partition-by odd? [1 1 1 2 2 3 3])
((1 1 1) (2 2) (3 3))
user=> (partition-by even? [1 1 1 2 2 3 3])
((1 1 1) (2 2) (3 3))
;; (this is part of a solution from 4clojure.com/problem 30)
user=> (partition-by identity "Leeeeeerrroyyy")
((\\L) (\\e \\e \\e \\e \\e \\e) (\\r \\r \\r) (\\o) (\\y \\y \\y))
;; Note that previously created 'bins' are not used when same value is seen again
user=> (partition-by identity "ABBA")
((\\A) (\\B \\B) (\\A))
;; That is why you use group-by function if you want all the the same values in the same 'bins' :)
;; Which gives you a hash, but you can extract values from that if you need.
(group-by identity "ABBA")
=> {\\A [\\A \\A], \\B [\\B \\B]}
;; Arbitrary partitioning
(let [seen (atom true)]
(partition-by #(cond
(#{1} %) (reset! seen (not @seen))
(or (and (string? %)
(< (count %) 2))
(char? %)) "letter"
(string? %) "string"
(#{0} %) 0
(vector? %) (count %)
:else "rest")
[1 1 1 2 3 nil "a" \\l 0 4 5 {:a 1} "bc" "aa" "k" [0] [1 1] [2 2]]))
;;=> ((1) (1) (1) (2 3 nil) ("a" \\l) (0) (4 5 {:a 1}) ("bc" "aa") ("k") ([0]) ([1 1] [2 2]))
user=> (partition-by count ["a" "b" "ab" "ac" "c"])
;;=> (("a" "b") ("ab" "ac") ("c"))