2

This is a question about how to properly collect the results from a nested for loop in Clojure. Suppose you want to create a sequence of all vectors [i j] where 0<=j<i<4

The following code

(for [i (range 1 4)] 
  (for [j (range i)] 
     [i j]
  )
)

produces

(([1 0]) ([2 0] [2 1]) ([3 0] [3 1] [3 2]))

but what I really want to get is

([1 0] [2 0] [2 1] [3 0] [3 1] [3 2])

What is the right way to do this?

Notice that I'm not interested in this specific sequence. My purpose here is to learn how to collect results from a nested for loop, which I need for a more complex problem.

2
  • FYI for in Clojure is not like for in C or Java. Having a for nested in an other for is rather unusual. Clojure for is a list comprehension function, it helps you create a list. See Python list comprehension for exemples. Commented Feb 2, 2016 at 8:29
  • Thanks. I tried the approach you are suggesting and it it really cleaner. Commented Feb 2, 2016 at 8:30

2 Answers 2

6

Don't nest two loops, rather use one loop with two iterators:

(for [i (range 1 4)
      j (range i)] 
   [i j])
Sign up to request clarification or add additional context in comments.

Comments

3

Assuming you have to use nested for loops, apply concat is the preferred way to flatten a sequence by one level

=> (apply concat 
         (for [i (range 1 4)] 
           (for [j (range i)] 
             [i j])))

([1 0] [2 0] [2 1] [3 0] [3 1] [3 2])

@Oin's solution is always preferable, unless the inner loop depends on the outer loop.

1 Comment

Thanks. This is exactly what I was looking for.

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.