Jedyne, co znalazłem, to działa
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
ale to wydaje daleko zbyt skomplikowane, aby być „prawo” sposób.
Jedyne, co znalazłem, to działa
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
ale to wydaje daleko zbyt skomplikowane, aby być „prawo” sposób.
Odpowiedzi:
cl-map
Zamiast tego użyj :
(cl-map 'vector #'1+ [1 2 3 4])
Trochę ekstra tła: cl-map
jest Common Lisp map
funkcja , która uogólnia typów sekwencji:
(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"
Może także konwertować między typami sekwencji (np. Tutaj dane wejściowe to lista, a dane wyjściowe to wektor):
(cl-map 'vector #'1+ '(1 2 3 4)) ;; ==> [2 3 4 5]
cl
biblioteką, a nie cl-lib
biblioteką zmienioną . Na przykład nie otrzymuję żadnych ostrzeżeń, kiedy ja (defun fnx () (cl-map 'vector #'1+ '[1 2 3 4]))
i wtedy (byte-compile 'fnx)
.
Ponieważ zostałem pokonany przez 18 sekund, oto prostszy i bezpieczniejszy sposób na zrobienie tego bez biblioteki cl. Nie ocenia też elementów.
(apply #'vector (mapcar #'1+ [1 2 3 4])) ;; => [2 3 4 5]
cl-lib
zależności.
apply
.
(apply #'vector ...)
może być jeszcze trochę szybszy, ale dla kompletności można go również zastąpić (vconcat ...)
.
Niezbyt elegancki wariant lokalny dla przypadku, gdy oryginalny wektor nie jest już potrzebny, a przydział pamięci jest krytyczny czasowo (np. Wektor jest duży).
(setq x [1 2 3 4])
(cl-loop for var across-ref x do
(setf var (1+ var)))
Wynik jest przechowywany w x
. Jeśli potrzebujesz formularza do powrotu x
, możesz dodać finally return x
w następujący sposób:
(cl-loop for var across-ref x do
(setf var (1+ var))
finally return x)
Dla kompletności, używając seq
:
(require 'seq)
(seq-into (seq-map #'1+ [1 2 3 4]) 'vector)
Możesz użyć pętli
(let ((v (vector 1 2 3 4)))
(dotimes (i (length v))
(aset v i (1+ (aref v i))))
v)
;; => [2 3 4 5]
Czasami nie chcesz modyfikować oryginalnego wektora, możesz wykonać kopię
(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])
lub utwórz nowy wektor od zera
(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
biblioteki nie ostrzegają jednak kompilatora? (Głównie dlatego, że FSF jest wstrętny?)