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.
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]
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]
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)
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])