# Multiple loops

**URL:** https://discourse.julialang.org/t/multiple-loops/23422
**Category:** General Usage
**Tags:** loops
**Created:** [April 22, 2019, 11:18pm UTC](https://discourse.julialang.org/t/multiple-loops/23422 "2019-04-22T23:18:00Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![Baicai\_Xiao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baicai_xiao/32/7395_2.png) [@Baicai\_Xiao](https://discourse.julialang.org/u/Baicai_Xiao)
#### Post date: [April 22, 2019, 11:18pm UTC](https://discourse.julialang.org/t/multiple-loops/23422/1 "2019-04-22T23:18:00Z")

</div>

Hello,

I tried to write some code on multiple but unknown number of loops. But didn’t find ways to do it. Can someone give me a hint? Thanks in advanced.  
Suppose I have an array

```julia
a = [2,3,4,5]

```

I want to write a loop that is equivalent to the following

```julia
A = Array{Array{Int64}}(undef,0)
for i_1 in 1:a[1]
       for i_2 in 1:a[2]
             for i_3 in 1:a[3]
                 for i_4 in 1:a[4]
                   append!(A,[[i_1,i_2,i_3,i_4]])
                 end
             end
       end
end

```

output will be

```julia
A 
144-element Array{Array{Int64,N} where N,1}:
 [1, 1, 1, 1]
 [1, 1, 1, 2]
 [1, 1, 1, 3]
 [1, 1, 1, 4]
 [1, 1, 1, 5]
 [1, 1, 2, 1]
 [1, 1, 2, 2]
 [1, 1, 2, 3]
 [1, 1, 2, 4]

.
.
.

```

But in a more general way, so that it will also can deal with for other 1D arrays like

```julia
a = [2,3,4,5,6]
a = [2,3,4,5,6,7]

```

Baicai

---

<div class="post-metadata">

### Author: ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)
#### Post date: [April 22, 2019, 11:18pm UTC](https://discourse.julialang.org/t/multiple-loops/23422/2 "2019-04-22T23:18:49Z")

</div>

I think this may be useful:

> **[Multidimensional algorithms and iteration](https://julialang.org/blog/2016/02/iteration/)**
>
> Multidimensional algorithms and iteration | Julia makes it easy to write elegant and...

---

<div class="post-metadata">

### Author: ![RaulDurand](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rauldurand/32/2044_2.png) [@RaulDurand](https://discourse.julialang.org/u/RaulDurand)
#### Post date: [April 23, 2019, 1:48am UTC](https://discourse.julialang.org/t/multiple-loops/23422/3 "2019-04-23T01:48:25Z")

</div>

You might want to use macros to generate multiple loops if the size of `a` is known at compile time.

---

<div class="post-metadata">

### Author: ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)
#### Post date: [April 23, 2019, 3:04am UTC](https://discourse.julialang.org/t/multiple-loops/23422/4 "2019-04-23T03:04:56Z")

</div>

with some tricks and the comments above, i did an awfully looking function that does what you requested, maybe it can be of some help

```julia
function testfunc(x::Array{II,1}) where II <: Integer
    A = Array{Array{Int64,1},1}(undef,reduce(*,x)) #prealocate array
    A0 = Array{Int8,length(x)}(undef,tuple(x...)...) 
#this matrix have in his indices the values that we want

    k = 1 
    for idx in CartesianIndices(A0)
    A[k] = vcat(Tuple(idx)...) 
    #tried to use collect, the error message recommended this
    k +=1
end
return A
end`

```

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [April 23, 2019, 3:43am UTC](https://discourse.julialang.org/t/multiple-loops/23422/5 "2019-04-23T03:43:49Z")

</div>

Use recursion. Metaprogramming and Cartesians can work, but it’s just overkill and much more complex than a simple recursive implementation.

---

<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: [April 23, 2019, 7:12am UTC](https://discourse.julialang.org/t/multiple-loops/23422/6 "2019-04-23T07:12:27Z")

</div>

I believe this solution iterates in the wrong order, it should be the last index incrementing first:

```julia
julia> testfunc([2,3,4])
24-element Array{Array{Int64,1},1}:
 [1, 1, 1]
 [2, 1, 1]
 [1, 2, 1]
 [2, 2, 1]
 [1, 3, 1]
 [2, 3, 1]
 [1, 1, 2]
...

```

---

<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: [April 23, 2019, 7:22am UTC](https://discourse.julialang.org/t/multiple-loops/23422/7 "2019-04-23T07:22:41Z")

</div>

Here’s one attempt that uses `Iterators.product`:

```julia
function myprod(v)
    x = [1:n for n in reverse(v)]
    return vec([[reverse(p)...] for p in Iterators.product(x...)])
end

```

It gets complicated because you want to increment the last elements first. Otherwise you could drop the `reverse` calls.

You could optimize it in various ways: using `Iterators.reverse(v)` instead of `reverse(v)`, if you could use tuples instead of vectors you wouldn’t need to splat `[reverse(p)...]`, and so on.

---

<div class="post-metadata">

### Author: ![rfourquet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rfourquet/32/3610_2.png) [@rfourquet](https://discourse.julialang.org/u/rfourquet)
#### Post date: [April 23, 2019, 7:26am UTC](https://discourse.julialang.org/t/multiple-loops/23422/8 "2019-04-23T07:26:19Z")

</div>

EDIT: oups, @DNF proposed a similar solution based on `Iterators.product` 2min earlier already!

Here is a simple solution for the specific case of your question. It doesn’t output exactly what you asked for, but can easily be adjusted:

```julia
julia> foreach(Iterators.product((1:x for x in a)...)) do i
           push!(A, [i...])
       end

julia> A
120-element Array{Array{Int64,N} where N,1}:
 [1, 1, 1, 1]
 [2, 1, 1, 1]
 [1, 2, 1, 1]
 [2, 2, 1, 1]
 [1, 3, 1, 1]
 [2, 3, 1, 1]
 [1, 1, 2, 1]
 [2, 1, 2, 1]
 [1, 2, 2, 1]
 [2, 2, 2, 1]
 [1, 3, 2, 1]
 [2, 3, 2, 1]
 [1, 1, 3, 1]
 [2, 1, 3, 1]
 [1, 2, 3, 1]
 [2, 2, 3, 1]
 [1, 3, 3, 1]
 [2, 3, 3, 1]
 [1, 1, 4, 1]
 [2, 1, 4, 1]
 [1, 2, 4, 1]
 ⋮

```

---

<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: [April 23, 2019, 8:59am UTC](https://discourse.julialang.org/t/multiple-loops/23422/9 "2019-04-23T08:59:31Z")

</div>

> [@Baicai\_Xiao](#):
>
> `A = Array{Array{Int64}}(undef,0)`

BTW, it is a bit important to realize that `Array{Int}` is an _abstract_ type, and using this can make a negative impact on performance, and even introduce bugs.

If you want a one-dimensional array, you have to write `Array{Int, 1}`, _not_ `Array{Int}`. This is also why I recommend using `Vector{Int}` and `Matrix{Int}`, instead of `Array`. It is too easy to forget the dimension parameter, and it’s also harder to read.

---

<div class="post-metadata">

### Author: ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)
#### Post date: [April 23, 2019, 3:52pm UTC](https://discourse.julialang.org/t/multiple-loops/23422/10 "2019-04-23T15:52:09Z")

</div>

another implementation, using a looped\_counter function that gives the next element, using recursion, you can add the type annotations and size checks to improve performance later, but this proof of concept works and gives you the order that you want

```julia
function looped_counter(x0,xmin, xmax,k=length(x0))
    x = copy(x0)
    k == 0 && return copy(xmin)
    if x[k]==xmax[k]
        x[k] = xmin[k]
        looped_counter(x,xmin,xmax,k-1)
    elseif x[k]<xmax[k]
        x[k]+=1
        return x
    else
        throw("wtf")
    end
end

function myfunc(xmin,xmax)
    A = Array{Array{Int64,1},1}(undef,0)
    a = copy(xmin)
    a = looped_counter(a,xmin,xmax)
    while a!= xmin
        push!(A,a)
        a = looped_counter(a,xmin,xmax)
    end
    return A
end

```

a simple example:

```julia
xmin = [1,1,1]
xmax = [3,4,3]
myfunc[xmin,xmax]

35-element Array{Array{Int64,1},1}:
 [1, 1, 2]
 [1, 1, 3]
 [1, 2, 1]
 [1, 2, 2]
 [1, 2, 3]
 [1, 3, 1]
 [1, 3, 2]
 [1, 3, 3]
 [1, 4, 1]
 [1, 4, 2]
 [1, 4, 3]
 [2, 1, 1]
 ⋮
 [3, 1, 2]
 [3, 1, 3]
 [3, 2, 1]
 [3, 2, 2]
 [3, 2, 3]
 [3, 3, 1]
 [3, 3, 2]
 [3, 3, 3]
 [3, 4, 1]
 [3, 4, 2]
 [3, 4, 3]

```

an advantage of the implementation is that you can use a different xmin to give different results (and it can be used as a clock, IDK)
