Fork me on GitHub
#beginners
<
2023-09-13
>
Sam Ferrell21:09:44

Is there a better strategy than what I've got here for partitioning a collection with a predicate?

(let [xs [:a 1 2 3 4 5 :b 6 :c 7 8 9]]
  (into [] (comp (partition-by keyword?)
                 (partition-all 2)
                 (map (partial apply into)))
        xs))
;; [[:a 1 2 3 4 5] [:b 6] [:c 7 8 9]]

tomd21:09:14

That usually works. But read here (disclaimer: it's by me) for more detail: https://www.juxt.pro/blog/new-medley-partition-fns/

👀 1
Bob B22:09:18

I think a question would come down to 'better in what way'? with the provided strategy, if the vector doesn't start with a keyword, then the outcome is sort of the reverse of what I think is desired:

(let [xs [0 :a 1 2 3 4 5 :b 6 :c 7 8 9]]
  (into [] (comp (partition-by keyword?)
                 (partition-all 2)
                 (map (partial apply into)))
        xs))
=> [[0 :a] [1 2 3 4 5 :b] [6 :c] [7 8 9]]
Another different approach besides the above would be to find the indexes that match the pred and then subvec them:
(let [t [0 :a 1 2 3 4 5 :b 6 :c 7 8 9]]
  (->> (keep-indexed #(when (keyword? %2) %1) t)
       (partition-all 2 1)
       (map #(apply subvec t %))))
=> ([:a 1 2 3 4 5] [:b 6] [:c 7 8 9])
This drops elements before the first keyword, which might be desired or undesired; this is just a thrown together example that could be tweaked as desired

👍 1
Sam Ferrell22:09:56

@UE1N3HAJH ahh not an uncommon problem then, cool. love medley. at least im not missing something obvious

Sam Ferrell22:09:00

thanks!

👍 1