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-map
es 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]
cl
biblioteca anterior en lugar de la cl-lib
biblioteca 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-lib
dependencia.
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 x
al final, puede agregar finally return x
lo 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-into
lí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])
cl
embargo, ¿las bibliotecas no dan advertencias al compilador? (¿Principalmente porque la FSF es desagradable?)