Das einzige, was ich gefunden habe, das funktioniert, ist
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
Aber das scheint viel zu kompliziert, um der richtige Weg zu sein.
Das einzige, was ich gefunden habe, das funktioniert, ist
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
Aber das scheint viel zu kompliziert, um der richtige Weg zu sein.
Antworten:
Verwenden Sie cl-map
stattdessen:
(cl-map 'vector #'1+ [1 2 3 4])
Ein kleiner zusätzlicher Hintergrund: cl-map
ist die Common Lisp- map
Funktion , die sich auf Sequenztypen verallgemeinert:
(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"
Es kann auch zwischen Sequenztypen konvertiert werden (hier ist z. B. die Eingabe eine Liste und die Ausgabe ein Vektor):
(cl-map 'vector #'1+ '(1 2 3 4)) ;; ==> [2 3 4 5]
cl
der Bytekompilierung eher mit der alten Bibliothek als mit der neu ausgelösten cl-lib
Bibliothek zusammenhängen. Ich bekomme zum Beispiel keine Warnungen, wenn ich (defun fnx () (cl-map 'vector #'1+ '[1 2 3 4]))
und dann (byte-compile 'fnx)
.
Da ich 18 Sekunden hinter mir habe, ist dies eine einfachere und sicherere Möglichkeit, ohne die cl-Bibliothek vorzugehen. Die Elemente werden auch nicht bewertet.
(apply #'vector (mapcar #'1+ [1 2 3 4])) ;; => [2 3 4 5]
cl-lib
Abhängigkeit austauschen.
apply
.
(apply #'vector ...)
vielleicht etwas schneller, aber der Vollständigkeit halber kann es auch durch ersetzt werden (vconcat ...)
.
Die nicht so elegante Inplace-Variante für den Fall, dass der ursprüngliche Vektor danach nicht mehr benötigt wird und die Speicherzuordnung zeitkritisch ist (zB der Vektor ist groß).
(setq x [1 2 3 4])
(cl-loop for var across-ref x do
(setf var (1+ var)))
Das Ergebnis wird in gespeichert x
. Wenn Sie das Formular benötigen, um es x
am Ende zurückzugeben, können Sie finally return x
Folgendes hinzufügen :
(cl-loop for var across-ref x do
(setf var (1+ var))
finally return x)
Der Vollständigkeit halber mit seq
:
(require 'seq)
(seq-into (seq-map #'1+ [1 2 3 4]) 'vector)
seq-into
Linie. Der Benutzer hat seine Antwort aus folgendem Grund gelöscht: "Meine Lösung ist weniger relevant, da die seq-Bibliothek die zugrunde liegenden Common Lisp-Erweiterungen verwendet. - Fólkvangr 16. Mai um 8:53"
Sie können Schleife verwenden
(let ((v (vector 1 2 3 4)))
(dotimes (i (length v))
(aset v i (1+ (aref v i))))
v)
;; => [2 3 4 5]
Manchmal möchten Sie den ursprünglichen Vektor nicht ändern, sondern können eine Kopie erstellen
(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])
oder erstellen Sie einen neuen Vektor von Grund auf neu
(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
Geben die Bibliotheken jedoch keine Compiler-Warnungen aus? (Meistens, weil die FSF widerlich ist?)