Wednesday 27 July 2011

Transforming Sequences

So with those points in mind here are two examples from 4Clojure.

To pack a sequence - that is to take all runs of one or more equal elements and put them inside their own sub-sequences. At each turn round the loop get the next element and then use take-while to gather equal ones into a sub-list and use drop-while to skip over the ones waiting to be processed, like this:

(defn pack-sequence [sq]
  (loop [src sq, dest []]
    (if (seq src)
      (let [x (first src)]
        (recur
          (drop-while #(= x %) src)
          (conj dest (take-while #(= x %) src))))
      dest)))


So for example (pack-sequence '(1 1 2 2 2 3) => '((1 1) (2 2 2) (3))

And similarly to replicate a sequence, meaning to duplicate each element a nominated number of times: use repeat to do the duplication and concat to add the elements to the growing destination sequence:

(defn replicate-sequence [sq n]
  (loop [src sq, dest []]
    (if (seq src)
      (recur
        (rest src)
        (concat dest (repeat n (first src))))
    dest)))


So for example (replicate-sequence '(1 2 3) 2) => '(1 1 2 2 3 3)

No comments:

Post a Comment