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.
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
biblioteki nie ostrzegają jednak kompilatora? (Głównie dlatego, że FSF jest wstrętny?)cl
biblioteką, a niecl-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.
źródło
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).
Wynik jest przechowywany w
x
. Jeśli potrzebujesz formularza do powrotux
, możesz dodaćfinally return x
w następujący sposób:źródło
Dla kompletności, używając
seq
:źródło
seq-into
linią. Użytkownik usunął swoją odpowiedź z następującego powodu: „Moje rozwiązanie jest mniej istotne, ponieważ biblioteka seq korzysta z podstawowych rozszerzeń Common Lisp. - Fólkvangr 16 maja o 8:53”Możesz użyć pętli
Czasami nie chcesz modyfikować oryginalnego wektora, możesz wykonać kopię
lub utwórz nowy wektor od zera
źródło