Skip to content

Latest commit

 

History

History
65 lines (49 loc) · 1.94 KB

removing-an-item.asciidoc

File metadata and controls

65 lines (49 loc) · 1.94 KB

"Removing" an item from a vector

Problem

You want to remove an item from a vector, obtaining a new vector without the item.

Solution

To efficiently remove an item from the end of a vector, use the pop function, which takes a vector and returns a new vector without the last item.

(pop [1 2 3 4])
;; -> [1 2 3]

Although there is no operation designed specifically to remove items from the beginning of a vector, as pop does from the end, there is a function - subvec - that can be used to efficiently 'remove' any number of items from the beginning or end of a vector. Given a vector, a start index and an (optional) end index, it will return a vector from the start (inclusive) to end (exclusive) indexes.

The following example drops a single item from the beginning of a vector, you can use subvec like so:

(subvec [:a :b :c :d] 1)
;; -> [:b :c :d]

Or, to remove items from the beginning and the end of a vector, pass an end index to subvec as well:

(subvec [:a :b :c :d] 1 3)
;; -> [:b :c]
Discussion

Because subvec exploits the internal representation of a vector to create a sub-vector that shares internal structure with the original, it is extremely efficient and runs in constant time. It is the only way to efficiently 'remove' items from the beginning of a vector.

While it is certainly also possible to use a function like rest or drop on a vector, these are technically sequence operations, not vector operations. The value they return is only guaranteed to be a sequence, not a concrete vector, and as such will not support the same features or performance guarantees that vectors do.

Of course, you can convert any sequence back into a concrete vector using vec or into [], but this can be an expensive operation for large vectors.

See also
  • Removing an item from a list (xref)

  • Removing items from a sequence (xref)