La répétition des vecteurs dans Clojure
-
01-10-2019 - |
Question
Je suis un newbie Clojure. Je suis en train d'obtenir deux copies d'un vecteur de combinaisons de cartes. La manière non Dry que je peux trouver est
(def suits [:clubs :diamonds :hearts :spades])
(def two-times (concat suits suits))
Il doit y avoir une façon plus fonctionnelle (même si cela prend plus de caractères :-)). Que faire si je veux N fois? Toutes les suggestions?
Toutes les choses que j'essaie, comme
(replicate 2 suits)
résultats dans deux vecteurs séparés:
([:clubs :diamonds :hearts :spades] [:clubs :diamonds :hearts :spades])
Comment puis-je "aplatis" la structure?
La solution
concat
vous donne un seq paresseux. Si vous voulez retrouver avec un vecteur (non paresseux) à la place:
user> (into suits suits)
[:clubs :diamonds :hearts :spades :clubs :diamonds :hearts :spades]
user> (reduce into (replicate 2 suits))
[:clubs :diamonds :hearts :spades :clubs :diamonds :hearts :spades]
Selon que vous accédez à ce par index beaucoup ou itère dessus, soit un vecteur ou suivants pourraient être plus approprié.
Il y a toujours cycle
aussi, si vous voulez un flux sans fin (paresseux) d'éléments répétés:
user> (take 9 (cycle suits))
(:clubs :diamonds :hearts :spades :clubs :diamonds :hearts :spades :clubs)
Autres conseils
Un peu d'expérimentation avec le REPL me conduisent à cette solution:
user=> (def suits [:clubs :diamonds :hearts :spades])
#'user/suits
user=> suits
[:clubs :diamonds :hearts :spades]
user=> (reduce concat (replicate 2 suits))
(:clubs :diamonds :hearts :spades :clubs :diamonds :hearts :spades)
(! Non testé)
(apply concat (repeat 2 suits))
, nous l'espérons faire l'affaire.
concat
sera bien sûr concaténer 2 listes; apply
peut être utilisé pour faire passer une fonction donnée dans la position de la tête d'une liste existante pour l'évaluation.
(take (* 2 (count suits)) (cycle suits))