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'.
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
embargo, ¿las bibliotecas no dan advertencias al compilador? (¿Principalmente porque la FSF es desagradable?)cl
biblioteca anterior en lugar de lacl-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.
fuente
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).
El resultado se almacena en
x
. Si necesita que el formulario regresex
al final, puede agregarfinally return x
lo siguiente:fuente
Para completar, usando
seq
:fuente
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
A veces no desea modificar el vector original, puede hacer una copia
o crear un nuevo vector desde cero
fuente