# How to detect the last iteration in a loop

**URL:** <https://discourse.julialang.org/t/how-to-detect-the-last-iteration-in-a-loop/54833>\
**Category:** New to Julia\
**Created:** [February 8, 2021, 9:09am UTC](https://discourse.julialang.org/t/how-to-detect-the-last-iteration-in-a-loop/54833 "2021-02-08T09:09:29Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Laco\_Kovac](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laco_kovac/32/20684_2.png) [@Laco\_Kovac](https://discourse.julialang.org/u/Laco_Kovac)\
**Post date:** [February 8, 2021, 9:09am UTC](https://discourse.julialang.org/t/how-to-detect-the-last-iteration-in-a-loop/54833/1 "2021-02-08T09:09:29Z")

</div>

How do I detect the last iteration in a loop, e.g. generation INSERT INTO statement for several records:

```julia
sql = "INSERT INTO table VALUES "
for oneRecord in records # guaranteed that records is not empty
    sql *= "($val1, $val2, $oneRecord)"
    if islast # this statement I am asking about
        sql *= ";"
    else
        sql *= ", "
    end
end

```

I know I could use lenght and count iteration, but I think there must be something nicer.

Thank you,

---

<div class="post-metadata">

**Author:** ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)\
**Post date:** [February 8, 2021, 9:24am UTC](https://discourse.julialang.org/t/how-to-detect-the-last-iteration-in-a-loop/54833/2 "2021-02-08T09:24:14Z")

</div>

I wonder whether something like this might help:

```julia
records = Iterators.Stateful(1:10)
for i in records
    if peek(records) == nothing
        println(" <- that was the penultimate value")
    end
    println(i)
end

1
2
3
4
5
6
7
8
9
 <- that was the penultimate value
10

```

---

<div class="post-metadata">

**Author:** ![angusmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/angusmoore/32/5654_2.png) [@angusmoore](https://discourse.julialang.org/u/angusmoore)\
**Post date:** [February 8, 2021, 9:48am UTC](https://discourse.julialang.org/t/how-to-detect-the-last-iteration-in-a-loop/54833/4 "2021-02-08T09:48:00Z")

</div>

The idiom I like to use to solve this particular problem is to use `join`. `join` can be used to join together an Array of strings with a chosen separator. E.g:

```julia
sql = "INSERT INTO table VALUES "

inserts = ["($val1, $val2, $oneRecord)" for oneRecord in records]

sql *= join(inserts, ", ")

```

I’ve used an array comprehension to create a temporary Array `inserts` that have the nicely formatted strings you want to join together

(This does not answer your actual question of how to detect the last iteration: it’s a different way of solving the question in your code - which is a pattern I came across in my own work all the time.)

---

<div class="post-metadata">

**Author:** ![Laco\_Kovac](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laco_kovac/32/20684_2.png) [@Laco\_Kovac](https://discourse.julialang.org/u/Laco_Kovac)\
**Post date:** [February 8, 2021, 9:58am UTC](https://discourse.julialang.org/t/how-to-detect-the-last-iteration-in-a-loop/54833/5 "2021-02-08T09:58:50Z")

</div>

> [@cormullion](#):
>
> ```julia
> for i in records
> if peek(records) == nothing
> println(" <- that was the penultimate value")
> end
> println(i)
> end
> 
> ```

Suggested code works with UInt8, but when I use strings, as it is in my case:

```julia
records=["a", "b", "c"]

```

I am getting:

```julia
ERROR: MethodError: no method matching peek(::Array{String,1}, ::Type{UInt8})
Closest candidates are:
  peek(::Base.Iterators.Stateful, ::Any) at iterators.jl:1274
  peek(::REPL.Terminals.TTYTerminal, ::Type{T}) where T at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.5\REPL\src\Terminals.jl:163
  peek(::Base.AbstractPipe, ::Type{T}) where T at io.jl:358

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [February 8, 2021, 10:17am UTC](https://discourse.julialang.org/t/how-to-detect-the-last-iteration-in-a-loop/54833/6 "2021-02-08T10:17:28Z")

</div>

There is no way, in general, to know that an iteration is done until you actually get `nothing` back from `iterate` So you need to remember two values while iterating. This is how `join` does it:

> <https://github.com/JuliaLang/julia/blob/5ab3ed6415bacb2fd4dd41302bde010c46074c2f/base/strings/io.jl#L266-L281>

---

<div class="post-metadata">

**Author:** ![Laco\_Kovac](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laco_kovac/32/20684_2.png) [@Laco\_Kovac](https://discourse.julialang.org/u/Laco_Kovac)\
**Post date:** [February 8, 2021, 10:36am UTC](https://discourse.julialang.org/t/how-to-detect-the-last-iteration-in-a-loop/54833/7 "2021-02-08T10:36:59Z")

</div>

Thank you, @angusmoore , that’s exactly what I am going to use.

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [February 8, 2021, 11:18am UTC](https://discourse.julialang.org/t/how-to-detect-the-last-iteration-in-a-loop/54833/8 "2021-02-08T11:18:54Z")

</div>

You can do it in a different order

```julia
sql = "INSERT INTO table VALUES "
for (i, oneRecord) in enumerate(records) # guaranteed that records is not empty
    i != 1 && sql *= ", "
    sql *= "($val1, $val2, $oneRecord)"
end
sql *= ";"

```

---

<div class="post-metadata">

**Author:** ![Laco\_Kovac](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laco_kovac/32/20684_2.png) [@Laco\_Kovac](https://discourse.julialang.org/u/Laco_Kovac)\
**Post date:** [February 8, 2021, 11:57am UTC](https://discourse.julialang.org/t/how-to-detect-the-last-iteration-in-a-loop/54833/9 "2021-02-08T11:57:01Z")

</div>

@Skoffer Excellent, thank you!

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 8, 2021, 2:06pm UTC](https://discourse.julialang.org/t/how-to-detect-the-last-iteration-in-a-loop/54833/10 "2021-02-08T14:06:27Z")

</div>

I would also use `join`, but if you insist on a loop, you can also check for the _first_ element, and reorganize the logic a bit:

```julia
using InterTools
sql = "INSERT INTO table VALUES "
for (isfirst, oneRecord) in IterTools.flagfirst(records)
    if !isfirst
        sql *= ", "
    end
    sql *= "($val1, $val2, $oneRecord)"
end
sql *= ";"

```

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [February 8, 2021, 2:30pm UTC](https://discourse.julialang.org/t/how-to-detect-the-last-iteration-in-a-loop/54833/11 "2021-02-08T14:30:30Z")

</div>

The other solutions look good to me too, but to make the `Iterators.Stateful` one work, you just need to wrap the iterator (whatever it is, vector of strings or anything else) in `Iterators.Stateful`, and then just use the wrapper, e.g.

```julia
records=["a", "b", "c"]
itr = Iterators.Stateful(records)

for i in itr
    if peek(itr) == nothing
        println(" <- that was the penultimate value")
    end
    println(i)
end

```

yields

```julia
a
b
 <- that was the penultimate value
c

```

This is just a convienent way of doing the “remember values while iterating” for you.
