Điều duy nhất tôi thấy rằng hoạt động là
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
nhưng điều đó dường như xa quá phức tạp để có cách 'đúng'.
Điều duy nhất tôi thấy rằng hoạt động là
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
nhưng điều đó dường như xa quá phức tạp để có cách 'đúng'.
Câu trả lời:
Sử dụng cl-map
, thay vào đó:
(cl-map 'vector #'1+ [1 2 3 4])
Thêm một chút nền tảng: cl-map
là hàm Lispmap
chung để khái quát các loại trình tự:
(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"
Nó cũng có thể chuyển đổi giữa các loại trình tự (ví dụ, ở đây, đầu vào là một danh sách và đầu ra là một vectơ):
(cl-map 'vector #'1+ '(1 2 3 4)) ;; ==> [2 3 4 5]
cl
thư viện cũ hơn là cl-lib
thư viện được đánh giá lại . Tôi không ví dụ, nhận được bất kỳ cảnh báo khi tôi (defun fnx () (cl-map 'vector #'1+ '[1 2 3 4]))
và sau đó (byte-compile 'fnx)
.
Vì tôi bị đánh bại 18 giây, đây là cách đơn giản và an toàn hơn để làm điều đó mà không cần thư viện cl. Nó cũng không đánh giá các yếu tố.
(apply #'vector (mapcar #'1+ [1 2 3 4])) ;; => [2 3 4 5]
cl-lib
phụ thuộc.
apply
.
(apply #'vector ...)
có thể nhanh hơn một chút, nhưng để hoàn thiện, nó cũng có thể được thay thế bằng (vconcat ...)
.
Biến thể inplace không thanh lịch cho trường hợp vectơ ban đầu không còn cần thiết sau đó và phân bổ bộ nhớ là thời gian quan trọng (ví dụ: vectơ là lớn).
(setq x [1 2 3 4])
(cl-loop for var across-ref x do
(setf var (1+ var)))
Kết quả được lưu trữ trong x
. Nếu bạn cần biểu mẫu để trả lại x
cuối cùng, bạn có thể thêm finally return x
như sau:
(cl-loop for var across-ref x do
(setf var (1+ var))
finally return x)
Để hoàn thiện, sử dụng seq
:
(require 'seq)
(seq-into (seq-map #'1+ [1 2 3 4]) 'vector)
Bạn có thể sử dụng vòng lặp
(let ((v (vector 1 2 3 4)))
(dotimes (i (length v))
(aset v i (1+ (aref v i))))
v)
;; => [2 3 4 5]
Đôi khi bạn không muốn sửa đổi vectơ gốc, bạn có thể tạo một bản sao
(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])
hoặc tạo một vectơ mới từ đầu
(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
Tuy nhiên, các thư viện không đưa ra cảnh báo về trình biên dịch? (Chủ yếu là vì FSF đáng ghét?)