Search code examples
clojuresequences

How can I remove an item from a sequence in Clojure?


First, I assume each structure-specific sequences would have different ways to remove an item: Vectors could be by index, List could be remove first or last, Set should be passing of the actual item to remove, etc.

Second, I assume there are some methods for removal that are structure agnostic; they work on seq interface.

Since sequences are immutable in Clojure, I suspect what you're actually doing is making a cheap copy of the original, only without the original item. This means list comprehension could be used for removal, but I suspect it would be unnecessarily verbose.

Please give some idiomatic examples of the different ways to remove items from Clojure sequences.


Solution

  • There is no single interface for removing things from all of Clojure's data structure types, possibly because of the different performance characteristics.

    (disj #{:foo :bar} :foo)       ; => #{:bar}
    (dissoc {:foo 1 :bar 2} :foo)  ; => {:bar 2}
    (pop [:bar :foo])              ; => [:bar]
    (pop (list :foo :bar))         ; => (:bar)
    

    These also work (returning a seq):

    (remove #{:foo} #{:foo :bar})      ; => (:bar)
    (remove #{:foo} [:foo :bar])       ; => (:bar)
    (remove #{:foo} (list :foo :bar))  ; => (:bar)
    

    This doesn't work for hash-maps because when you iterate over a map, you get key/value pairs. But this works:

    (remove (fn [[k v]] (#{:foo} k)) {:foo 1 :bar 2})  ; => ([:bar 2])