dansalmo
dansalmo

Reputation: 11694

How can I remove an item by type from a nested list or vector in Clojure?

Is there a way to remove items in a nested list by type such that (1 [2] 3 (4 [5] 6)) becomes (1 3 (4 6)) if I want to remove just the vectors?

Using postwalk, I can replace all vectors with nil, but I can not find a way to remove them.

(clojure.walk/postwalk 
  #(if (vector? %) nil %) '(1 [2] 3 (4 [5] 6)))

=>(1 nil 3 (4 nil 6))

Upvotes: 7

Views: 899

Answers (2)

Alex D
Alex D

Reputation: 30465

I'd love to see a more concise solution using clojure.walk, but here is one which uses a recursive function and mapcat:

(defn remove-vectors [coll]
  (mapcat
     (fn [x]
       (cond
         (vector? x) nil
         (coll? x) (list (remove-vectors x))
         :else (list x)))
     coll))

And one which uses filter and map:

(defn remove-vectors [coll]
  (map #(if (coll? %) (remove-vectors %) %) (remove vector? coll)))

Upvotes: 2

DanLebrero
DanLebrero

Reputation: 8591

Far from perfect but perhaps it is a good start:

 (clojure.walk/prewalk #(if (list? %) (remove vector? %) %) '(1 [2] 3 (4 [5] 6)))

Upvotes: 5

Related Questions