tags:

views:

100

answers:

5

Sorry for the noob question, but is there an good way to destructure values from a sequence like this..

(somefunc [[a b c] [1 2 3 4 5 6 7 8 9]] (prn a b c))

..with the a b c being assigned values until the sequence exhausted and letting me call a function on the args? doseq requires a partition of the right size..

(doseq [[a b c] (partition 3 [1 2 3 4 5 6 7 8 9])] (prn a b c))

Output:

1 2 3 4 5 6 7 8 9

That does what I want, but it seems like there should be a way to do this in s straightforward way without having to specify the partition. I found a solution with loop/recur but it's a lot more code and clearly non-idiomatic. What's a good way to do this? Thanks!

+2  A: 
(defn some-func
  [[a b c & rest :as all]]
  (prn a b c)
  (prn rest)
  (prn all)

user> (some-func [1 2 3 4 5 6 7])
1 2 3
(4 5 6 7)
[1 2 3 4 5 6 7]

Read more about destructing: http://java.ociweb.com/mark/clojure/article.html#Destructuring

edbond
+2  A: 
(defn apply-to-three [f [a b c & rest]]
  (f a b c)
  (when rest
    (recur f rest)))

user=> (apply-to-three prn [1 2 3 4 5 6 7 8 9])
1 2 3
4 5 6
7 8 9
nil
ponzao
that's the same partition and map does.
edbond
@edbond Naturally there are different ways to solve any given problem. A down vote usually implies that there is something fundamentally wrong with the answer, could you please elaborate what your problem is with mine?
ponzao
@ponzao: I don't like reimplementing core functions, it's not idiomatic.
edbond
A: 

Using map and partition:

(map prn (partition 3 [1 2 3 4 5 6 7 8 9]))
Matti Pastell
+1  A: 

partition + map is all you need. Read about dorun, doseq and doall: http://onclojure.com/2009/03/04/dorun-doseq-doall/

user> (dorun (map #(apply prn %) (partition 3 [1 2 3 4 5 6 7 8 9])))
1 2 3
4 5 6
7 8 9
nil
edbond
You probably want to use `partition-all` instead of `partition`, otherwise you will lose values if the length of the collection is not dividable by 3.
ponzao
@ponzao: sure, you're right.
edbond
+1  A: 
Alex Taggart