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-mapinvece:
(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]
cllibreria piuttosto che alla cl-liblibreria 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-libdipendenza.
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 xcome 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])
clbiblioteche non danno avvertimenti al compilatore? (Soprattutto perché la FSF è odiosa?)