This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
Hi! How can I group by two all elements of a list of lists?
((1) (2) (3) (4) (5)) ;=> ((1 2) (3 4) (5))
in general, a good place to start is to look through the seq library, https://clojure.org/reference/sequences#_seq_in_seq_out
What if instead of partition by 2
I use a given condition? e.g. #(split-here? %) ;=> true/false
((1) (2) (3) (4) (5) (6) (7)) ;=> ((1 2) (3) (4) (5 6 7))
I’ve tried partition-by
but groups items together. I’ve a collection of has-map ordered and I’ve to split them when a value of an item is null.
(partition-by #(nil? (:key %)) coll)
is not what I expectwhat do you want ?
(partition-by #(-> % :k nil?)
[{:k 1} {:k 2} {:k nil} {:k 3} {:k 4}])
(({:k 1} {:k 2}) ({:k nil}) ({:k 3} {:k 4}))
sounds like what you wantI was looking more for
[{:k 1} {:k 2} {:k nil} {:k 3} {:k 4}]
(({:k 1} {:k 2}) ({:k nil} {:k 3} {:k 4}))
something like (split-when f coll)
(defn split-when [f coll]
(loop [xs coll
acc [[]]]
(if-let [x (first xs)]
(if (f x)
(recur (rest xs)
(conj acc [x]))
(recur (rest xs)
(conj (pop acc) (conj (peek acc) x))))
acc)))
not sure if there’s a better way to do ityou could always define it as a transducer to avoid consuming the whole collection to decide when to split. Maybe something like:
(defn split-when [f]
(fn [rf]
(let [col (volatile! [])]
(fn
([] (rf))
([r]
(rf (if (seq @col)
(rf r @col)
r)))
([r x]
(if (f x)
(let [v (rf r @col)]
(vreset! col [x])
v)
(do (vswap! col conj x)
r)))))))
(comment
(sequence (comp (map inc)
(split-when #{5}))
(range 10)) ;=> ([1 2 3 4] [5 6 7 8 9 10])
)
??in the clojure definition of macroexpand, why does it use an equality check as the termination condition for the recursion rather than directly checking whether the first element is a macro? is it because in order to check whether something is a macro you have to resolve it, which is somehow limiting?