Search code examples
clojureclojurescript

Loop through vector of vectors and remove element from vector in Clojure


I am new to clojure programming and would like some help with some code. I have this vector of vectors like below,

(def start-pos [[[:fox :goose :corn :you] [:boat] []]])

I would like to loop through the vector and remove an element from one of the internal vectors, e.g. remove ':goose' from start-pos.

I tried the code below but for some reason it doesnt work as intended,

(map #(disj (set %) :goose) start-pos)

Instead the result is,

(#{[:boat] [] [:fox :goose :corn :you]})

As you can see from the result, the internal vectors are now a set and yes, the original order is distorted, is there a way of removing the element and not disarrange the original order of the vectors, maybe without converting it to a set first? I choose this conversion to a set first because according to the docs disj only works for sets.

Add: This post is not similar to this suggested post as my vector is nested three vectors deep.


Solution

  • the internal vectors are now a set

    That's because the result of #(disj (set %) :goose) returns a set.

    original order is distorted

    Sets don't preserve insertion order by default, similar to maps with over 8 keys.

    I would like to loop through the vector and remove an element from one of the internal vectors, e.g. remove ':goose' from start-pos.

    The function you need for removing an element from a collection by predicate is called remove, but...

    The value you want to remove is actually nested three vectors deep in start-pos, so you'd need an additional iteration for each inner vector, and so on if you wanted to remove the keyword :goose from every vector recursively. That's an excuse to use clojure.walk:

    (clojure.walk/postwalk
      (fn [v]
        (if (coll? v)
          (into (empty v) (remove #{:goose}) v)
          v))
      start-pos)
    => [[[:fox :corn :you] [:boat] []]]
    

    This walks every value in start-pos, removing :goose from any collections it finds.