La seule chose que j'ai trouvée qui fonctionne est
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
mais cela semble beaucoup trop compliqué pour être la «bonne» façon.
La seule chose que j'ai trouvée qui fonctionne est
(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]
mais cela semble beaucoup trop compliqué pour être la «bonne» façon.
Réponses:
Utilisez cl-map
plutôt:
(cl-map 'vector #'1+ [1 2 3 4])
Un petit arrière-plan supplémentaire: cl-map
est la fonction Common Lispmap
qui se généralise aux types de séquence:
(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"
Il peut également convertir entre les types de séquence (par exemple, ici, l'entrée est une liste et la sortie est un vecteur):
(cl-map 'vector #'1+ '(1 2 3 4)) ;; ==> [2 3 4 5]
cl
bibliothèque plutôt qu'à la cl-lib
bibliothèque relancée . Je ne suis pas, par exemple, obtenir des avertissements quand je (defun fnx () (cl-map 'vector #'1+ '[1 2 3 4]))
puis (byte-compile 'fnx)
.
Depuis que j'ai été battu de 18 secondes, voici un moyen plus simple et plus sûr de le faire sans la bibliothèque cl. Il n'évalue pas non plus les éléments.
(apply #'vector (mapcar #'1+ [1 2 3 4])) ;; => [2 3 4 5]
cl-lib
dépendance.
apply
.
(apply #'vector ...)
pourrait être un peu plus rapide, mais pour être complet, il peut également être remplacé par (vconcat ...)
.
La variante inplace pas si élégante pour le cas où le vecteur d'origine n'est plus nécessaire par la suite et l'allocation de mémoire est critique en temps (par exemple, le vecteur est grand).
(setq x [1 2 3 4])
(cl-loop for var across-ref x do
(setf var (1+ var)))
Le résultat est stocké dans x
. Si vous avez besoin du formulaire pour retourner x
à la fin, vous pouvez ajouter finally return x
comme suit:
(cl-loop for var across-ref x do
(setf var (1+ var))
finally return x)
Pour être complet, utilisez seq
:
(require 'seq)
(seq-into (seq-map #'1+ [1 2 3 4]) 'vector)
Vous pouvez utiliser la boucle
(let ((v (vector 1 2 3 4)))
(dotimes (i (length v))
(aset v i (1+ (aref v i))))
v)
;; => [2 3 4 5]
Parfois, vous ne voulez pas modifier le vecteur d'origine, vous pouvez en faire une copie
(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])
ou créez un nouveau vecteur à partir de zéro
(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
bibliothèques ne donnent-elles pas d'avertissements au compilateur, cependant? (Surtout parce que la FSF est odieuse?)