8

How can I/should I pass a single sequence as an argument to a function which expects multiple arguments? Specifically, I'm trying to use cartesian-product and pass it a sequence (see below); however, when I do so the result is not the desired one. If I can't pass a single sequence as the argument, how can I/should I break up the sequence into multiple arguments? Thanks.

(use '[clojure.contrib.combinatorics :only (cartesian-product)])
(cartesian-product (["a" "b" "c"] [1 2 3]))

Results in:

((["a" "b"]) ([1 2]))

Desired result

(("a" 1) ("a" 2) ("b" 1) ("b" 2))
Ari
  • 4,121
  • 8
  • 40
  • 56

2 Answers2

10

the apply function builds a function call from a function and a sequence containing the arguments to the function.

(apply cartesian-product  '(["a" "b" "c"] [1 2 3]))
(("a" 1) ("a" 2) ("a" 3) ("b" 1) ("b" 2) ("b" 3) ("c" 1) ("c" 2) ("c" 3))

as another example:

(apply + (range 10))

evaluates (range 10) into a sequence (0 1 2 3 4 5 6 7 8 9) and then builds this function call

(+ 0 1 2 3 4 5 6 7 8 9)


and back by popular demand:

fortunatly the for function does this nicely.

(for [x ["a" "b"] y [1 2]] [x y])
(["a" 1] ["a" 2] ["b" 1] ["b" 2])
Arthur Ulfeldt
  • 90,827
  • 27
  • 201
  • 284
  • sorry for the pun... I will edit to add a real answer also in a moment – Arthur Ulfeldt Oct 12 '11 at 19:59
  • Note that you should use vectors in preference to quoted lists since the latter would prevent evaluation of the elements. – Alex Taggart Oct 13 '11 at 07:10
  • @Ari, if you click on the text after "edited" you can see old revisions. I'm not sure why you took the for(tunate) example out; seems an appropriate and simple solution to me. I suppose it needs to be used in combination with destructing or equivalent to be a full solution, but it's still informative. – Adrian Mouat Oct 14 '11 at 08:23
1

apply is one way as Arthur shows.

Another possibility to consider is destructuring. Specifically nested vector binding:

user=> (let [[v1 v2] '([:a :b] [1 2])]
         (cartesian-product v1 v2))

Alex Stoddard
  • 8,244
  • 4
  • 41
  • 61
  • Thanks for sharing an alternative solution; I appreciate it. I selected Arthur's suggestion, because the sequence argument, in my problem, is of variable size. – Ari Oct 12 '11 at 23:36