for an arbitrary iterator that's not possible unless you first save the results of every iteration into a seq.
Though say if you iterate about a seq, you can do this:
for i, item in pairs mySeq:
if i == mySeq.len-1:
echo "last"
or if you iterate over a table:
var i = 0
for k, v, in pairs myTable:
if i == myTable.len-1:
echo "last"
i += 1
Note that you can also use mySeq.high which is the highest index, this also means you can do non-zero indexed arrays:
var x: array[5..10, int]
for i, v in x:
echo "x[", i, "] = ", v
if i == x.len - 1:
echo "Not last :("
if i == x.high:
echo "Last iteration :)"
Use this logic to see if you need to insert a seperator:
result = ""
var i = 0
for it in items(collection):
if i > 0: result.add ", "
result.add $it
inc i
You almost never need to know if it's the "last" iteration, the "first" iteration suffices and is much easier to test for.
Minor nit picky changes:
for idx, item in mySeq:
if idx == mySeq.high:
echo "last"
if you really need the last item of an iteration, you could do something like this:
template lastItem(last: untyped, iteration: untyped, body: untyped): bool =
var hasLast = false
var `last` {.inject.}: typeof(iteration())
for it in iteration():
hasLast = true
`last` = it
body
hasLast
iterator test1(): int {.inline.} =
yield 10
yield 20
yield 30
proc main() =
var hasLast = lastItem(it, [1,2,3,4,5].items):
echo it
if hasLast : echo "last was ", it
hasLast = lastItem(it2, test1):
echo it2
if hasLast : echo "last was ", it2
main()