Welcome! Please see the About page for a little more info on how this works.

0 votes
in Collections by

i want to create a list of pairs, and can build the list best as a series of pairs of pairs:

(for [ni (range n)
          di (range d)]
     (let [j1 (mod (inc di) n)
              j2 (mod (- n (inc di)) n) ]
          (conj [] [ni j1] [ni j2]) ))

this gets me close:

([[0 1] [0 9]] [[0 2] [0 8]] [[1 1] [1 9]]...

but is adding an extra level of brackets. what i want would look like this:

([0 1] [0 9] [0 2] [0 8] [1 1] [1 9] ...

I am confident there is a simple solution for this but I can't figure out what it!?

2 Answers

0 votes
by
selected by
 
Best answer

Another option is using the pairs as another set of binding:

(for [ni (range n)
      di (range d)
      :let [j1 (mod (inc di) n)
            j2 (mod (- n (inc di)) n)]
      p [[ni j1] [ni j2]]]
  p)

The "interesting" expression doesn't have to be in the return position of for :)

by
sweet, thank you!  and thanks also @alexmiller.  i'm preferring this answer because it better preserves the clarifying `for` structure
0 votes
by

There are many ways to do it, one would be changing from for to using nested mapcats.

(mapcat 
  (fn [ni] 
    (mapcat 
      (fn [di] 
        (let [j1 (mod (inc di) n)
              j2 (mod (- n (inc di)) n)]
          [[ni j1] [ni j2]])) 
      (range d))) 
  (range n))
...