0

I have a function

(defn x [w]
  (let [[w1 w2 w3] w]
    (println w1)
    (println w2)
    (println w3))) 

If I call the function

(x [[1 1] [2 2] [3 3]])
=> [1 1]
   [2 2]
   [3 3]

which is what I expect

Is there a way to generalise this? In this case I knew that w was a vector containing 3 vectors so I know to have [w1 w2 w3] If w was then a vector of 4 vectors, the last vector would not be set to anything

What I want is where w is a vector of n vectors and then in the let of the function set them to [w1 w2 w3 ... wn]? (note doesn't necessarily have to be w1, w2, ... wn)

The println are just there for debugging so not that important for the function

Any help would be much appreciated.

2
  • 3
    How are you going to refer to w1, w2 etc if you don't know how many there are? It sounds like you should process the incoming sequence instead of destructuring it. Commented Apr 25, 2017 at 11:16
  • 2
    map, reduce, transduce, filter are but a few collection processing functions available that don't need hard coded associations to the collection elements. You will grow to love these... Commented Apr 25, 2017 at 11:52

1 Answer 1

4
(defn x [ws]
  (dorun (map println ws)))

For example,

(x [[1 1] [2 2] [3 3]])
[1 1]
[2 2]
[3 3]
=> nil
  • The map applies println to each of the ws in turn, returning the nil results as a sequence, on demand (lazily).
  • The dorun demands the whole sequence, discarding it as it goes, returning nil.

If you want to see the sequence, replace dorun with doall:

(defn x [ws]
  (doall (map println ws)))

=> (x [[1 1] [2 2] [3 3]])
[1 1]
[2 2]
[3 3]
=> (nil nil nil)

A more concise alternative to the former is

(defn x [ws]
  (doseq [w ws] (println w)))

... and to the latter is

(defn x [ws]
  (for [w ws] (println w)))
Sign up to request clarification or add additional context in comments.

2 Comments

I realize you're using println for illustrative purposes only, but in case anyone reading thinks (doall (map println ws)) is a good idea for general use, I wanted to comment to discourage its use. For side-effecting processing of a collection where you don't care about the result, the modern clojure best practice is run!: (run! println coll) (doall (map... is wrong probably 80% of the time (discounting REPL use). Again, your answer uses println only as an example, so this isn't a comment about your answer itself, just for general info for anyone reading. Upvoted your answer.
@Josh Thanks, Josh. I didn't know about run!. As for println, I just followed what OP did. My clumsy code is to tease out the sequence processing (the real point of the question, I suspect) from the side-effect issue.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.