Единственное, что я нашел, это работает
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
но кажется , что далеко слишком сложно , чтобы быть «правильный» путь.
Единственное, что я нашел, это работает
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
но кажется , что далеко слишком сложно , чтобы быть «правильный» путь.
Ответы:
Используйте cl-mapвместо этого:
(cl-map 'vector #'1+ [1 2 3 4])
Немного дополнительного фона: cl-mapэто функция Common Lisp,map которая обобщает типы последовательностей:
(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"
Он также может преобразовывать типы последовательностей (например, здесь вход является списком, а выход - вектором):
(cl-map 'vector #'1+ '(1 2 3 4)) ;; ==> [2 3 4 5]
clбиблиотекой, а не с перенастроенной cl-libбиблиотекой. Я, например, не получаю никаких предупреждений, когда я, (defun fnx () (cl-map 'vector #'1+ '[1 2 3 4]))а затем (byte-compile 'fnx).
Поскольку меня избили 18 секунд, вот более простой и безопасный способ сделать это без библиотеки cl. Это также не оценивает элементы.
(apply #'vector (mapcar #'1+ [1 2 3 4])) ;; => [2 3 4 5]
cl-libзависимости.
apply.
(apply #'vector ...)может быть немного быстрее, но для полноты его также можно заменить на (vconcat ...).
Не очень элегантный вариант на месте для случая, когда исходный вектор больше не нужен, а распределение памяти критично ко времени (например, вектор большой).
(setq x [1 2 3 4])
(cl-loop for var across-ref x do
(setf var (1+ var)))
Результат сохраняется в x. Если вам нужна форма для возврата xв конце, вы можете добавить finally return xследующее:
(cl-loop for var across-ref x do
(setf var (1+ var))
finally return x)
Для полноты, используя seq:
(require 'seq)
(seq-into (seq-map #'1+ [1 2 3 4]) 'vector)
Вы можете использовать цикл
(let ((v (vector 1 2 3 4)))
(dotimes (i (length v))
(aset v i (1+ (aref v i))))
v)
;; => [2 3 4 5]
Иногда вы не хотите изменять исходный вектор, вы можете сделать копию
(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])
или создайте новый вектор с нуля
(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библиотеки не выдают предупреждения компилятора? (Главным образом потому, что ФСФ противна?)