Repeating vectors in Clojure

I am new to Clojure. I am trying to get two copies of the card suit vector. Wrong DRY way I can think of,

(def suits [:clubs :diamonds :hearts :spades]) (def two-times (concat suits suits)) 

There should be a more functional way (even if it takes more characters :-)). What if I want N times? Any suggestions?

Everything I try, for example

 (replicate 2 suits) 

leads to two separate vectors:

 ([:clubs :diamonds :hearts :spades] [:clubs :diamonds :hearts :spades]) 

How to "smooth" the structure?

+6
clojure sequences playing-cards
source share
4 answers

concat gives you a lazy track. If you want to end up using a (not lazy) vector:

 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] 

Depending on whether you get it a lot by index or iterate over it, it may be more appropriate to use a vector or seq.

Always always cycle if you want an infinite (lazy) stream of repeating elements:

 user> (take 9 (cycle suits)) (:clubs :diamonds :hearts :spades :clubs :diamonds :hearts :spades :clubs) 
+7
source share

(unverified!)

 (apply concat (repeat 2 suits)) 

hope will do the trick.

concat , of course, combines 2 lists; apply can be used to smuggle this function to the head position of an existing list for evaluation.

+2
source share

A little experimentation with REPL leads me to this 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) 
+2
source share
 (take (* 2 (count suits)) (cycle suits)) 
+1
source share

All Articles