How can I map over a vector and get a vector?

The only thing I've found that works is

``````(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
``````

but that seems far too complicated to be the 'right' way.

Use `cl-map`, instead:

``````(cl-map 'vector #'1+ [1 2 3 4])
``````

A little extra background: `cl-map` is the Common Lisp `map` function that generalizes to sequence types:

``````(cl-map 'vector #'1+ '[1 2 3 4]) ;; ==> [2 3 4 5]
(cl-map 'list   #'1+ '(1 2 3 4)) ;; ==> (2 3 4 5)
(cl-map 'string #'upcase "abc")  ;; ==> "ABC"
``````

It can also convert between sequence types (eg, here, the input is a list and the output is a vector):

``````(cl-map 'vector #'1+ '(1 2 3 4)) ;; ==> [2 3 4 5]
``````
• 18 seconds the 'winner' :) Don't the `cl` libraries give compiler warnings, though? (Mostly because the FSF is obnoxious?) – Sean Allred Nov 1 '14 at 14:51
• FWIW, I think the byte compilation problems were related to the old `cl` library rather than the rejiggered `cl-lib` library. I don't for example, get any warnings when I `(defun fnx () (cl-map 'vector #'1+ '[1 2 3 4]))` and then `(byte-compile 'fnx)`. – Dan Nov 1 '14 at 15:01
• Even if you use the compatibility cl-lib, I think you'll get warnings on older emacs (24.2). I wouldn't worry about it though, you have to pick your battles. – Malabarba Nov 1 '14 at 15:07
• Note that this dynamically creates a list, then converts that to a vector and discards the temporary list. – Clément Apr 13 '20 at 22:05

Since I was beat by 18 seconds, here's a simpler and safer way to do it without the cl library. It also doesn't evaluate the elements.

``````(apply #'vector (mapcar #'1+ [1 2 3 4])) ;; => [2 3 4 5]
``````
• That's also quite nice! Re: your earlier comment about older Emacs: it seems especially helpful if you have to anticipate legacy users. It seems most helpful if you only have to use it in a couple of spots, at which point you can trade off the slight inconvenience against avoiding the `cl-lib` dependency. – Dan Nov 1 '14 at 15:27
• Very nifty!! I didn't think about using `apply`. – Sean Allred Nov 1 '14 at 22:51
• I think `(apply #'vector ...)` might be ever so slightly faster, but for completeness, it can also be replaced with `(vconcat ...)`. – Basil Nov 12 '18 at 20:03

The not so elegant inplace-variant for the case that the original vector is no longer needed afterwards and memory allocation is time-critical (e.g. the vector is big).

``````(setq x [1 2 3 4])

(cl-loop for var across-ref x do
(setf var (1+ var)))
``````

The result is stored in `x`. If you need the form to return `x` in the end you can add `finally return x` as follows:

``````(cl-loop for var across-ref x do
(setf var (1+ var))
finally return x)
``````

For completeness, using `seq`:

``````(require 'seq)
(seq-into (seq-map #'1+ [1 2 3 4]) 'vector)
``````
• There is a deleted answer from Fólkvangr 2018-11-12 with the exact same `seq-into` line. The user has deleted his answer for the following reason: " My solution is less relevant because the seq library uses the underlying Common Lisp extensions. – Fólkvangr May 16 at 8:53" – Tobias Jun 19 '19 at 7:28
• @Tobias I guess I'd disagree with that logic. Everything is going to end up using vconcat or vector anyway, but the different interface paradigms are useful to have on record. – Sean Allred Jun 19 '19 at 10:31
• No problem. I just saw the deleted answer of Fólkvangr (almost) matching yours and wanted to notify you. For whatever reason seeing deleted answers requires 10000 rep:-(. – Tobias Jun 19 '19 at 11:02
• @Tobias yeah, I never really understood why those privileges were site-specific :-) – Sean Allred Jun 19 '19 at 11:07

You can use loop

``````(let ((v (vector 1 2 3 4)))
(dotimes (i (length v))
(aset v i (1+ (aref v i))))
v)
;; => [2 3 4 5]
``````

Sometimes you don't want to modify the original vector, you can make a copy

``````(let* ((v0 (vector 1 2 3 4))
(v (copy-sequence v0)))
(dotimes (i (length v))
(aset v i (1+ (aref v i))))
(list v0 v))
;; => ([1 2 3 4] [2 3 4 5])
``````

or create a new vector from scratch

``````(let* ((v0 (vector 1 2 3 4))
(v (make-vector (length v0) nil)))
(dotimes (i (length v))
(aset v i (1+ (aref v0 i))))
(list v0 v))
;; => ([1 2 3 4] [2 3 4 5])
``````