A única coisa que descobri que funciona é
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
mas que parece muito muito complicado para ser a maneira 'certa'.
Use cl-map
, em vez disso:
(cl-map 'vector #'1+ [1 2 3 4])
Um pouco mais de fundo: cl-map
é a função Common Lispmap
que generaliza para tipos de sequência:
(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"
Também pode converter entre tipos de sequência (por exemplo, aqui, a entrada é uma lista e a saída é um vetor):
(cl-map 'vector #'1+ '(1 2 3 4)) ;; ==> [2 3 4 5]
cl
bibliotecas não dão avisos ao compilador? (Principalmente porque a FSF é detestável?)cl
biblioteca antiga , e não àcl-lib
biblioteca rejeitada . Por exemplo, não recebo nenhum aviso quando(defun fnx () (cl-map 'vector #'1+ '[1 2 3 4]))
e quando(byte-compile 'fnx)
.Desde que fui derrotado por 18 segundos, eis uma maneira mais simples e segura de fazê-lo sem a biblioteca cl. Também não avalia os elementos.
fonte
cl-lib
dependência.apply
.(apply #'vector ...)
pode ser um pouco mais rápido, mas, para ser completo, também pode ser substituído por(vconcat ...)
.A variante local não tão elegante para o caso que o vetor original não é mais necessário posteriormente e a alocação de memória é de tempo crítico (por exemplo, o vetor é grande).
O resultado é armazenado em
x
. Se você precisar retornar o formuláriox
no final, poderá adicionarfinally return x
o seguinte:fonte
Para completar, use
seq
:fonte
seq-into
linha exata . O usuário excluiu sua resposta pelo seguinte motivo: "Minha solução é menos relevante porque a biblioteca seq usa as extensões Common Lisp subjacentes. - Fólkvangr 16 de maio às 8:53"Você pode usar loop
Às vezes, você não deseja modificar o vetor original, pode fazer uma cópia
ou crie um novo vetor do zero
fonte