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'.
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'.
Respostas:
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
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.
(apply #'vector (mapcar #'1+ [1 2 3 4])) ;; => [2 3 4 5]
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).
(setq x [1 2 3 4])
(cl-loop for var across-ref x do
(setf var (1+ var)))
O resultado é armazenado em x
. Se você precisar retornar o formulário x
no final, poderá adicionar finally return x
o seguinte:
(cl-loop for var across-ref x do
(setf var (1+ var))
finally return x)
Para completar, use seq
:
(require 'seq)
(seq-into (seq-map #'1+ [1 2 3 4]) 'vector)
Você pode 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]
Às vezes, você não deseja modificar o vetor original, pode fazer uma cópia
(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])
ou crie um novo vetor do zero
(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
bibliotecas não dão avisos ao compilador? (Principalmente porque a FSF é detestável?)