# Loops for unknown numbers of inputs

**URL:** https://discourse.julialang.org/t/loops-for-unknown-numbers-of-inputs/85773
**Category:** General Usage
**Tags:** question
**Created:** [August 15, 2022, 12:33pm UTC](https://discourse.julialang.org/t/loops-for-unknown-numbers-of-inputs/85773 "2022-08-15T12:33:58Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![Funkerfish](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/funkerfish/32/37982_2.png) [@Funkerfish](https://discourse.julialang.org/u/Funkerfish)
#### Post date: [August 15, 2022, 12:33pm UTC](https://discourse.julialang.org/t/loops-for-unknown-numbers-of-inputs/85773/1 "2022-08-15T12:33:58Z")

</div>

Hello!  
Now I am trying to make functions to form a matrix which can traverse all the values of input. Can you help with that?  
Suppose that we have three arrays:

```julia
as = [1,2]
bs = [3,4, 5]
cs = [6]

```

Then I want to build a matrix that includes all the possible combinations

```julia
nloop = length(as) * length(bs) * length(cs)
num_set = zeros(nloop, 3)
loop_num = 1
 for (ia, va) in enumerate(as), (ib, vb) in enumerate(bs), (ic, vc) in enumerate(cs)
num_set[loop_num, :] .= [va,vb,vc]
global loop_num += 1
end

```

then output should be:

```julia
6×3 Matrix{Float64}:
 1.0 3.0 6.0
 2.0 3.0 6.0
 1.0 4.0 6.0
 2.0 4.0 6.0
 1.0 5.0 6.0
 2.0 5.0 6.0

```

What if I have few inputs of sets, for example:

```julia
as = [1,2]
bs = [3,4, 5]
cs = [6]
ds = [7, 8, 9]

```

How can I create a function to form a few loops according to the number of number sets? Many thanks in advance!

---

<div class="post-metadata">

### Author: ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)
#### Post date: [August 15, 2022, 12:43pm UTC](https://discourse.julialang.org/t/loops-for-unknown-numbers-of-inputs/85773/2 "2022-08-15T12:43:15Z")

</div>

I am surprised that [Combinatorics.jl](https://github.com/JuliaMath/Combinatorics.jl) doesn’t have this functionality already?

Maybe `Iterators.product` can help you out (also see `zip`)

---

<div class="post-metadata">

### Author: ![Funkerfish](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/funkerfish/32/37982_2.png) [@Funkerfish](https://discourse.julialang.org/u/Funkerfish)
#### Post date: [August 15, 2022, 12:51pm UTC](https://discourse.julialang.org/t/loops-for-unknown-numbers-of-inputs/85773/3 "2022-08-15T12:51:52Z")

</div>

Thank you! I would check `Iterators.product ` .

---

<div class="post-metadata">

### Author: ![Funkerfish](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/funkerfish/32/37982_2.png) [@Funkerfish](https://discourse.julialang.org/u/Funkerfish)
#### Post date: [August 15, 2022, 1:28pm UTC](https://discourse.julialang.org/t/loops-for-unknown-numbers-of-inputs/85773/4 "2022-08-15T13:28:22Z")

</div>

`Iterators.product` can solve my problem! But how can I transform the Array to Matrix{Float64}？

---

<div class="post-metadata">

### Author: ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)
#### Post date: [August 15, 2022, 1:34pm UTC](https://discourse.julialang.org/t/loops-for-unknown-numbers-of-inputs/85773/5 "2022-08-15T13:34:05Z")

</div>

This is most definitely not the most efficient way, but this matches your original output:

```julia
mapreduce(collect,hcat,Iterators.product(as,bs,cs))'

```

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [August 15, 2022, 1:41pm UTC](https://discourse.julialang.org/t/loops-for-unknown-numbers-of-inputs/85773/6 "2022-08-15T13:41:20Z")

</div>

It is more efficient and natural to turn it into a `3 x nloops` matrix instead of an `nloops x 3` matrix, since Julia arrays are column major and the tuples are adjacent in memory. In that case:

```julia
julia> reshape(reinterpret(Int, collect(Iterators.product(as, bs, cs))), 3, :)
3×6 reshape(reinterpret(Int64, ::Array{Tuple{Int64, Int64, Int64}, 3}), 3, 6) with eltype Int64:
 1 2 1 2 1 2
 3 3 4 4 5 5
 6 6 6 6 6 6

```

(On my laptop that’s \>6x as fast as the `mapreduce`.)

---

<div class="post-metadata">

### Author: ![Funkerfish](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/funkerfish/32/37982_2.png) [@Funkerfish](https://discourse.julialang.org/u/Funkerfish)
#### Post date: [August 15, 2022, 1:51pm UTC](https://discourse.julialang.org/t/loops-for-unknown-numbers-of-inputs/85773/7 "2022-08-15T13:51:33Z")

</div>

Thank you! really helpful!

---

<div class="post-metadata">

### Author: ![Funkerfish](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/funkerfish/32/37982_2.png) [@Funkerfish](https://discourse.julialang.org/u/Funkerfish)
#### Post date: [August 15, 2022, 1:51pm UTC](https://discourse.julialang.org/t/loops-for-unknown-numbers-of-inputs/85773/8 "2022-08-15T13:51:45Z")

</div>

Thank you!

---

<div class="post-metadata">

### Author: ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)
#### Post date: [August 15, 2022, 2:22pm UTC](https://discourse.julialang.org/t/loops-for-unknown-numbers-of-inputs/85773/9 "2022-08-15T14:22:50Z")

</div>

just for fun

```julia
function hmprod(v...)
    prod=[]
    for a in v[1], b in v[2]
        push!(prod, [a...,b])
        end
        prod
    end

hcat(reduce(hmprod, ads)...)

```

---

<div class="post-metadata">

### Author: ![Funkerfish](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/funkerfish/32/37982_2.png) [@Funkerfish](https://discourse.julialang.org/u/Funkerfish)
#### Post date: [August 15, 2022, 3:27pm UTC](https://discourse.julialang.org/t/loops-for-unknown-numbers-of-inputs/85773/10 "2022-08-15T15:27:44Z")

</div>

Thank you! I am wondering how `for a in v[1], b in v[2]` can work for unknown numbers of inputs. Seems I should read more about `...`. BTW, your code is more friendly for mixed types of input arrays. Thank you all!

---

<div class="post-metadata">

### Author: ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)
#### Post date: [August 15, 2022, 3:55pm UTC](https://discourse.julialang.org/t/loops-for-unknown-numbers-of-inputs/85773/11 "2022-08-15T15:55:56Z")

</div>

I’m not sure I fully understand your doubt, but the script, which is certainly not as efficient as the other proposals, should work for a generic number of input vectors.

```julia
julia> as = [1,2]
2-element Vector{Int64}:
 1
 2

julia> bs = (3,4, 5)
(3, 4, 5)

julia> cs = [6]
1-element Vector{Int64}:
 6

julia> ds = [7, 8, 9]
3-element Vector{Int64}:
 7
 8
 9

julia> ads=[as,bs,cs,ds]
4-element Vector{Any}:
 [1, 2]
 (3, 4, 5)
 [6]
 [7, 8, 9]

julia> reduce(hmprod, ads)
18-element Vector{Any}:
 (1, 3, 6, 7)
 (1, 3, 6, 8)
 (1, 3, 6, 9)
 (1, 4, 6, 7)
 (1, 4, 6, 8)
 (1, 4, 6, 9)
 (1, 5, 6, 7)
 (1, 5, 6, 8)
 (1, 5, 6, 9)
 (2, 3, 6, 7)
 (2, 3, 6, 8)
 (2, 3, 6, 9)
 (2, 4, 6, 7)
 (2, 4, 6, 8)
 (2, 4, 6, 9)
 (2, 5, 6, 7)
 (2, 5, 6, 8)
 (2, 5, 6, 9)

julia> function hmprod(v...)
           p=[]
           i=1
           for a in v[1], b in v[2]
               push!(p, (a...,b))
               i+=1
           end
               p
           end
hmprod (generic function with 1 method)

```

I add a recursive version, which does not use functions of either Base or other packages.

```julia
julia> function rhmprod(v...)
           p=Tuple[]
           i=1
           if length(v)>=2
               for a in v[1], b in v[2]
                   push!(p, (a...,b))
                   i+=1
               end
               rhmprod(p,v[3:end]...)
           else
               v[1]
           end
       end
rhmprod (generic function with 1 method)

julia> rhmprod(ads...)
18-element Vector{Tuple}:
 (1, 3, 6, 7)
 (1, 3, 6, 8)
 (1, 3, 6, 9)
 (1, 4, 6, 7)
 (1, 4, 6, 8)
 (1, 4, 6, 9)
 (1, 5, 6, 7)
 (1, 5, 6, 8)
 (1, 5, 6, 9)
 (2, 3, 6, 7)
 (2, 3, 6, 8)
 (2, 3, 6, 9)
 (2, 4, 6, 7)
 (2, 4, 6, 8)
 (2, 4, 6, 9)
 (2, 5, 6, 7)
 (2, 5, 6, 8)
 (2, 5, 6, 9)

```

---

<div class="post-metadata">

### Author: ![Funkerfish](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/funkerfish/32/37982_2.png) [@Funkerfish](https://discourse.julialang.org/u/Funkerfish)
#### Post date: [August 16, 2022, 6:49am UTC](https://discourse.julialang.org/t/loops-for-unknown-numbers-of-inputs/85773/12 "2022-08-16T06:49:08Z")

</div>

Thank you! I can understand your code now. but why we need the `i` to count the loop?

---

<div class="post-metadata">

### Author: ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)
#### Post date: [August 16, 2022, 6:23pm UTC](https://discourse.julialang.org/t/loops-for-unknown-numbers-of-inputs/85773/13 "2022-08-16T18:23:56Z")

</div>

It does not have anything to do with it.  
It’s just the remnant of a “refactoring” 😊.

PS  
consider that the solution based on the use of the product function is much, much better performing.
