İşe yaradığını bulduğum tek şey
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
ama görünüyor uzakta çok 'doğru' yol olarak karmaşık.
İşe yaradığını bulduğum tek şey
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
ama görünüyor uzakta çok 'doğru' yol olarak karmaşık.
Yanıtlar:
Kullanım cl-map
yerine,:
(cl-map 'vector #'1+ [1 2 3 4])
Biraz ekstra arka plan: dizi türlerine genelleme cl-map
yapan Ortak Lisp map
işlevidir :
(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"
Ayrıca dizi türleri arasında dönüştürme yapabilir (örn. Burada giriş bir listedir ve çıkış bir vektördür):
(cl-map 'vector #'1+ '(1 2 3 4)) ;; ==> [2 3 4 5]
cl
yapılandırılmış cl-lib
kütüphane yerine eski kütüphaneyle ilgili olduğunu düşünüyorum . Mesela ben (defun fnx () (cl-map 'vector #'1+ '[1 2 3 4]))
ve sonra hiçbir uyarı almıyorum (byte-compile 'fnx)
.
18 saniye boyunca dövüldüğüm için, cl kütüphanesi olmadan bunu yapmanın daha basit ve daha güvenli bir yolu var. Ayrıca unsurları değerlendirmez.
(apply #'vector (mapcar #'1+ [1 2 3 4])) ;; => [2 3 4 5]
cl-lib
bağımlılıktan kaçınmaya karşı hafif rahatsızlığı takas edebilirsiniz .
apply
.
(apply #'vector ...)
her zamankinden biraz daha hızlı olabilir, ancak tamlık için de değiştirilebilir (vconcat ...)
.
Orijinal vektörün artık sonradan ihtiyaç duyulmadığı ve bellek tahsisinin zaman açısından kritik olduğu durumlarda (örn. Vektör büyüktür) durum için o kadar şık olmayan yer-varyantı.
(setq x [1 2 3 4])
(cl-loop for var across-ref x do
(setf var (1+ var)))
Sonuç, içinde saklanır x
. x
Sonunda dönmek için forma ihtiyacınız varsa finally return x
aşağıdaki gibi ekleyebilirsiniz :
(cl-loop for var across-ref x do
(setf var (1+ var))
finally return x)
Tamlık için seq
:
(require 'seq)
(seq-into (seq-map #'1+ [1 2 3 4]) 'vector)
Döngüyü kullanabilirsiniz
(let ((v (vector 1 2 3 4)))
(dotimes (i (length v))
(aset v i (1+ (aref v i))))
v)
;; => [2 3 4 5]
Bazen orijinal vektörü değiştirmek istemezsiniz, bir kopyasını yapabilirsiniz
(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])
veya sıfırdan yeni bir vektör oluşturun
(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
Kütüphaneler derleyici uyarısı vermiyor mu? (Çoğunlukla FSF iğrenç olduğu için mi?)