# All vectors formed by picking one element from each vector

I’d like to write a vararg function which takes N vectors, and return all possible length-N vectors by picking one element from each vector. For example

``````all_vectors([['a', 'b'], [1, 2, 3], ['x']])
``````

should give the result

``````[['a', 1, 'x'], ['a', 2, 'x'], ['a', 3, 'x'], ['b', 1, 'x'], ['b', 2, 'x'], ['b', 3, 'x']]
``````

Although it’s not hard to write such a function, I’m wondering what the most concise and readable solution would look like.

Check out the built-in `Iterators.product` function:

``````help?> Iterators.product
product(iters...)

Return an iterator over the product of several iterators. Each generated element is a tuple whose ith element comes from the ith argument iterator. The first iterator changes the fastest.

Examples
≡≡≡≡≡≡≡≡≡≡

julia> collect(Iterators.product(1:2, 3:5))
2×3 Array{Tuple{Int64,Int64},2}:
(1, 3)  (1, 4)  (1, 5)
(2, 3)  (2, 4)  (2, 5)
``````

Note that `product` expects each iterator to be a separate argument, so you can take the product of an array of iterators by doing `product(my_vector_of_vectors...)` using `...` to splat the collection into multiple arguments.

Also, you may get better performance by storing a tuple of vectors instead of a vector of vectors, since your individual inner vectors have different types. That would look like:

``````julia> data = (['a', 'b'], [1, 2, 3], ['x'])
(['a', 'b'], [1, 2, 3], ['x'])

julia> Iterators.product(data...)
``````
2 Likes

Wow, that’s a very quick solution, thanks!