3

I am looking to write a function which inputs two vectors of length n,

i.e. [:a :b :c :d :e :f] [1 2 3 4 5 6]. Outputting one vector of length 2n

[:a 1 :b 2 :c 3 :d 4 :e 5 :f 6].

However, if the second vector being input doesn't match the length of n it will cycle,

i.e. [:a :b :c :d :e :f] [1 2 3]

outputs: [:a 1 :b 2 :c 3 :d 1 :e 2 :f 3].

 (defn Swanson [x y] (vec (flatten (interleave x (repeat (count x) y)))))

Moreover, the function can also take [x y min max n], where x and y are vectors, min is an index to start the interleaving, max is an index to end the interleaving, and n is a step-size for the interleaving.

sunspots
  • 1,047
  • 13
  • 29
  • 3
    I'd say the min/max/n arguments don't belong in this function - they add too many unrelated responsibilities. Instead, use a simple version of this function with just x/y, and combine take, drop, and take-nth (or something - I haven't worked through the details). Then if you want, you can build another function that takes all five args and calls the four relevant functions. – amalloy Nov 19 '13 at 22:04

4 Answers4

6

You want cycle:

user> (take 6 (cycle [1 2 3]))
(1 2 3 1 2 3)

user> (interleave [:a :b :c :d :e :f] (cycle [1 2 3]))
(:a 1 :b 2 :c 3 :d 1 :e 2 :f 3)
Alex
  • 13,811
  • 1
  • 37
  • 50
1

You can use the interleave function from the seq library for that:

=> (interleave [:a :b :c :d :e :f] [1 2 3 4 5 6])
(:a 1 :b 2 :c 3 :d 4 :e 5 :f 6)

Hope this helps!

Dirk Geurs
  • 2,392
  • 19
  • 24
1

for two any size vectors:

(defn cycleave [a b] 
  (let [c (max (count a) (count b))] 
    (take (* 2 c) (interleave (cycle a) 
                              (cycle b)))))

will give:

user => (cycleave [:a :b :c :d :e :f] [1 2 3])
(:a 1 :b 2 :c 3 :d 1 :e 2 :f 3)
tolitius
  • 22,149
  • 6
  • 70
  • 81
  • or if you only care about how long the first sequence is, you can simply do `(defn cycleave [a b] (interleave a (cycle b)))`, which will stop at the `(* 2 (count a))` elements – tolitius Nov 19 '13 at 20:49
  • if you want only `n` elements back: `(defn cycleave [a b n] (take n (interleave (cycle a) (cycle b))))` – tolitius Nov 19 '13 at 20:51
1

With x and y vectors, min the (inclusive) starting index, max the (exclusive) ending index, n the step size:

(defn swanson [x y min max n]
  (->> (interleave x (cycle y))
       (take max)
       (drop min)
       (take-nth n)))
omiel
  • 1,573
  • 13
  • 16