Pass Sequence as Argument in Place of Multiple Arguments
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 sing开发者_StackOverflowle 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))
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])
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))
精彩评论