L'unica cosa che ho scoperto che funziona è
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
ma che sembra di gran lunga troppo complicato per essere il modo 'giusto'.
L'unica cosa che ho scoperto che funziona è
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
ma che sembra di gran lunga troppo complicato per essere il modo 'giusto'.
Risposte:
Usa cl-map
invece:
(cl-map 'vector #'1+ [1 2 3 4])
Un piccolo sfondo extra: cl-map
è la funzione Common Lispmap
che si generalizza ai tipi di sequenza:
(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"
Può anche convertire tra tipi di sequenza (ad esempio, qui l'input è un elenco e l'output è un vettore):
(cl-map 'vector #'1+ '(1 2 3 4)) ;; ==> [2 3 4 5]
cl
libreria piuttosto che alla cl-lib
libreria reimpostata . Ad esempio, non ricevo alcun avviso quando io (defun fnx () (cl-map 'vector #'1+ '[1 2 3 4]))
e poi (byte-compile 'fnx)
.
Da quando sono stato battuto per 18 secondi, ecco un modo più semplice e sicuro per farlo senza la libreria cl. Inoltre non valuta gli elementi.
(apply #'vector (mapcar #'1+ [1 2 3 4])) ;; => [2 3 4 5]
cl-lib
dipendenza.
apply
.
(apply #'vector ...)
potrebbe essere leggermente più veloce, ma per completezza, può anche essere sostituito (vconcat ...)
.
La variante sul posto non così elegante per il caso in cui il vettore originale non è più necessario in seguito e l'allocazione della memoria è critica in termini di tempo (ad esempio, il vettore è grande).
(setq x [1 2 3 4])
(cl-loop for var across-ref x do
(setf var (1+ var)))
Il risultato è memorizzato in x
. Se alla fine è necessario il modulo da restituire, x
è possibile aggiungere finally return x
come segue:
(cl-loop for var across-ref x do
(setf var (1+ var))
finally return x)
Per completezza, usando seq
:
(require 'seq)
(seq-into (seq-map #'1+ [1 2 3 4]) 'vector)
Puoi usare il 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 volte non si desidera modificare il vettore originale, è possibile effettuare 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 crea un nuovo vettore da 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
biblioteche non danno avvertimenti al compilatore? (Soprattutto perché la FSF è odiosa?)