# Custom iterator, simple example

**URL:** <https://discourse.julialang.org/t/custom-iterator-simple-example/28212>\
**Category:** General Usage\
**Created:** [August 30, 2019, 2:59pm UTC](https://discourse.julialang.org/t/custom-iterator-simple-example/28212 "2019-08-30T14:59:34Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gus\_Hart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gus_hart/32/6987_2.png) [@Gus\_Hart](https://discourse.julialang.org/u/Gus_Hart)\
**Post date:** [August 30, 2019, 2:59pm UTC](https://discourse.julialang.org/t/custom-iterator-simple-example/28212/1 "2019-08-30T14:59:34Z")

</div>

I implemented Donald Knuth’s “Algorithm M” for generating all numbers in a mixed-radix numbering system. I would like to turn this into an _iterator_ so I could loop over all of them but without having them all in memory at the same time.

Here’s a simple case with the code:

```julia
m = [1,2,1]
nl = length(m)
a = zeros(Int,nl)
while true
    j = nl
    println(a)
    while true
      if a[j] < m[j] break; end
      a[j] = 0
      j -= 1
      if j==0 break; end
    end
    if j == 0 break; end
    a[j] += 1    
end

```

What I would like is something like this:

```julia
for i in MyMixedRadix([1,2,1])
   # code goes here
end

```

How do I turn my nested `for` loops into an iterator?

PS Here’s the output from the example:

```julia
[0, 0, 0]
[0, 0, 1]
[0, 1, 0]
[0, 1, 1]
[0, 2, 0]
[0, 2, 1]
[1, 0, 0]
[1, 0, 1]
[1, 1, 0]
[1, 1, 1]
[1, 2, 0]
[1, 2, 1]

```

---

<div class="post-metadata">

**Author:** ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)\
**Post date:** [August 30, 2019, 3:44pm UTC](https://discourse.julialang.org/t/custom-iterator-simple-example/28212/2 "2019-08-30T15:44:16Z")

</div>

I can give you a start:

```julia
struct MixedRadix{T}
  m::T
end
function Base.iterate(mr::MixedRadix)
    nl = length(mr.m)
    a = zeros(Int, nl)
    a, a # first iterate and the initial state
end
function Base.iterate(mr::MixedRadix, a)
    j = length(mr.m)
    
    ...

    if j == 0 
          return nothing
    end

    ...

    return a, a # state equals the last iterate
end
Base.IteratorSize(::MixedRadix) = Base.SizeUnkown()

```

---

<div class="post-metadata">

**Author:** ![Gus\_Hart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gus_hart/32/6987_2.png) [@Gus\_Hart](https://discourse.julialang.org/u/Gus_Hart)\
**Post date:** [August 30, 2019, 5:10pm UTC](https://discourse.julialang.org/t/custom-iterator-simple-example/28212/3 "2019-08-30T17:10:51Z")

</div>

Thanks for the reply…it raises another question for me. Why do I need a `struct`? It’s always going to be an array of `Int`s…

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [August 30, 2019, 6:06pm UTC](https://discourse.julialang.org/t/custom-iterator-simple-example/28212/4 "2019-08-30T18:06:50Z")

</div>

Because you want to tell the compiler it’s not _just any_ array of `Int`s, but ones with the special meaning. Normally, `iterate()` defined for arrays gives elements of array in order, the behavior you probably don’t want to change.

---

<div class="post-metadata">

**Author:** ![jlperla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlperla/32/34332_2.png) [@jlperla](https://discourse.julialang.org/u/jlperla)\
**Post date:** [August 30, 2019, 7:49pm UTC](https://discourse.julialang.org/t/custom-iterator-simple-example/28212/5 "2019-08-30T19:49:58Z")

</div>

> [@Gus\_Hart](#):
>
> I would like to turn this into an _iterator_ so I could loop over all of them but without having them all in memory at the same time.

If you are trying to learn the iterator protocol with this example, then listen to the others. But if you want to do this in your own code with high efficiency, I believe mixed-radix iteration is exactly what `CartesianIndices` is for.

```struct
ind = CartesianIndices((4, 2, 3))
display.(ind)

```

Or to be less concise in an example without broadcasting

```julia

for i in eachindex(ind)
    display(i)
end

```

---

<div class="post-metadata">

**Author:** ![Gus\_Hart](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gus_hart/32/6987_2.png) [@Gus\_Hart](https://discourse.julialang.org/u/Gus_Hart)\
**Post date:** [August 31, 2019, 8:33pm UTC](https://discourse.julialang.org/t/custom-iterator-simple-example/28212/6 "2019-08-31T20:33:38Z")

</div>

The was really helpful thanks. Indeed, I wasn’t so interested in making an iterator as in generating all _n_-tuples of a set. `CartesianIndices` seems to be just what I need.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [August 31, 2019, 10:24pm UTC](https://discourse.julialang.org/t/custom-iterator-simple-example/28212/7 "2019-08-31T22:24:30Z")

</div>

> [@Gus\_Hart](#):
>
> I implemented Donald Knuth’s “Algorithm M” for generating all numbers in a mixed-radix numbering system. I would like to turn this into an _iterator_ so I could loop over all of them but without having them all in memory at the same time.

Ranges of the `CartesianIndex` type indeed already do this for you (using a very efficient implementation involving generated functions). It loops in the opposite order from mixed-radix increments, but you can just call `reverse` to put it in radix order if needed:

```julia
julia> for i in CartesianIndex(0,0,0):CartesianIndex(1,2,1)
          println(reverse(Tuple(i)))
       end
(0, 0, 0)
(0, 0, 1)
(0, 1, 0)
(0, 1, 1)
(0, 2, 0)
(0, 2, 1)
(1, 0, 0)
(1, 0, 1)
(1, 1, 0)
(1, 1, 1)
(1, 2, 0)
(1, 2, 1)

```

(I don’t want to discourage you from learning how to implement iterators, but you are unlikely to beat the efficiency of `CartesianIndices` — it is implemented in pure-Julia code, but by an expert (@tim.holy).)

> [@jlperla](#):
>
> `ind = CartesianIndices((4, 2, 3))`

Note that using this constructor gives you 1-based indices, which may or may not be what you want. My example above gives you 0-based indices identical to your desired mixed-radix iteration.
