Tarmiac
Tarmiac

Reputation: 862

How do I iterate through two Sets in Clojure in order to return their Cartesian product?

So I take in two Sets and wanna iterate through them in order to return a new set containing the cross product of the two sets.

(defn cartesian
  "computes Cartesian product of A and B"

  [A B]
  

  use "set", "for")

I'm very new to Clojure so I'm not sure why use "set, "for" is included at all. But A and B will be Sets. Now I wanna iterate through each one and return the Cartesian product of them. Example:

(cartesian #{1 2} #{3 4 5}) => #{[1 3] [1 4] [1 5] [2 3] [2 4] [2 5]}

I'm not sure on the steps to get there though. I have looked through documentation etc but can't find what I'm looking for. Other answer to this deal with lists etc. But I have to use 2 Sets.

What I'm looking at atm is using doseq[e A] and inside that doseq[x B] then add each vector-pair [e x] to a new Set and then return it. This doesn't seem like a standard functional solution though. Am I on the right track? How do I add it to a new Set?

Upvotes: 0

Views: 174

Answers (2)

Martin Půda
Martin Půda

Reputation: 7568

Use cartesian-product from clojure.math.combinatorics. To get exact result you want (set of vectors), use into with map transducer:

(into #{} (map vec) (clojure.math.combinatorics/cartesian-product #{1 2} #{3 4 5}))
=> #{[2 3] [2 5] [1 4] [1 3] [1 5] [2 4]}

Upvotes: 1

Rulle
Rulle

Reputation: 4901

You can accomplish that using for:

(defn cartesian [A B]
  (set (for [a A
             b B]
         [a b])))

(cartesian #{1 2} #{3 4 5})
;; => #{[2 3] [2 5] [1 4] [1 3] [1 5] [2 4]}

Upvotes: 2

Related Questions