Lo único que he encontrado que funciona es
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
pero que parece ahora demasiado complicado para ser la forma 'correcta'.
Lo único que he encontrado que funciona es
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
pero que parece ahora demasiado complicado para ser la forma 'correcta'.
Respuestas:
Use cl-map, en cambio:
(cl-map 'vector #'1+ [1 2 3 4])
Un poco de información adicional: cl-mapes la función Common Lispmap que se generaliza a los tipos de secuencia:
(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"
También puede convertir entre tipos de secuencia (por ejemplo, aquí, la entrada es una lista y la salida es un vector):
(cl-map 'vector #'1+ '(1 2 3 4)) ;; ==> [2 3 4 5]
clbiblioteca anterior en lugar de la cl-libbiblioteca rejigger . Por ejemplo, no recibo ninguna advertencia cuando (defun fnx () (cl-map 'vector #'1+ '[1 2 3 4]))y luego (byte-compile 'fnx).
Como me vencieron 18 segundos, aquí hay una manera más simple y segura de hacerlo sin la biblioteca cl. Tampoco evalúa los elementos.
(apply #'vector (mapcar #'1+ [1 2 3 4])) ;; => [2 3 4 5]
cl-libdependencia.
apply.
(apply #'vector ...)podría ser un poco más rápido, pero para completar, también se puede reemplazar (vconcat ...).
La variante in situ no tan elegante para el caso de que el vector original ya no sea necesario después y la asignación de memoria es crítica en el tiempo (por ejemplo, el vector es grande).
(setq x [1 2 3 4])
(cl-loop for var across-ref x do
(setf var (1+ var)))
El resultado se almacena en x. Si necesita que el formulario regrese xal final, puede agregar finally return xlo siguiente:
(cl-loop for var across-ref x do
(setf var (1+ var))
finally return x)
Para completar, usando seq:
(require 'seq)
(seq-into (seq-map #'1+ [1 2 3 4]) 'vector)
seq-intolínea. El usuario ha eliminado su respuesta por la siguiente razón: "Mi solución es menos relevante porque la biblioteca seq utiliza las extensiones subyacentes de Common Lisp. - Fólkvangr 16 de mayo a las 8:53"
Puedes usar loop
(let ((v (vector 1 2 3 4)))
(dotimes (i (length v))
(aset v i (1+ (aref v i))))
v)
;; => [2 3 4 5]
A veces no desea modificar el vector original, puede hacer una copia
(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])
o crear un nuevo vector desde cero
(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])
clembargo, ¿las bibliotecas no dan advertencias al compilador? (¿Principalmente porque la FSF es desagradable?)