Единственное, что я нашел, это работает
(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
библиотеки не выдают предупреждения компилятора? (Главным образом потому, что ФСФ противна?)