Ripetendo vettori in Clojure
-
01-10-2019 - |
Domanda
Sono un novizio Clojure. Sto cercando di ottenere due copie di un vettore di abiti di carta. La mancata DRY modo che io possa venire in mente è
(def suits [:clubs :diamonds :hearts :spades])
(def two-times (concat suits suits))
Ci deve essere un modo più funzionale (anche se ci vuole più caratteri :-)). Che cosa se voglio N volte? Qualche suggerimento?
Tutte le cose che cerco, come
(replicate 2 suits)
Risultati di due vettori separati:
([:clubs :diamonds :hearts :spades] [:clubs :diamonds :hearts :spades])
Come faccio a "appiattire" la struttura?
Soluzione
concat
ti dà un ss pigro. Se si vuole finire con un vettore (non pigro) invece:
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]
A seconda se si sta accedendo questo indice molto o iterando su di esso, sia un vettore o un ss potrebbe essere più appropriato.
C'è sempre cycle
troppo, se si desidera un flusso infinito (pigro) di elementi ripetuti:
user> (take 9 (cycle suits))
(:clubs :diamonds :hearts :spades :clubs :diamonds :hearts :spades :clubs)
Altri suggerimenti
Un po 'di sperimentazione con il REPL mi portano a questa soluzione:
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 testata!)
(apply concat (repeat 2 suits))
si spera fare il trucco.
concat
sarà ovviamente concatenate 2 liste; apply
può essere usato per contrabbandare una data funzione nella posizione di testa di un elenco esistente per la valutazione.
(take (* 2 (count suits)) (cycle suits))