# How to use the iterator in Mathematica

I find that Mathematica has the iterator data structure. We can build some iterators like this:

### Constant iterator

GeneralUtilitiesConstantIterator[5]


### Key value iterator

GeneralUtilitiesKeyValueIterator[<|a -> x, b -> y, c -> z|>]


### Range iterator

GeneralUtilitiesRangeIterator[9]


We can find all iterator functions with

Names["GeneralUtilities*Iterator*"]


But I don't know how to process the iterator, as Mathematica has no function like next on Python:

>>> string='FhC'
>>> it=iter(string)
>>> next(it)
'F'
>>> next(it)
'h'


## Update

Michael E2's answer clear this problem a lot,But I hope the DelegateIterator, IteratorGraph, JoinMapIterator, SingletonIterator, StreamIterator, TerminatorIterator and ToIterator can be discussed still.

• Re update: Their code can be inspected and it's fairly easy to understand, since it's so short. – Michael E2 Jan 22 '17 at 21:08
• @MichaelE2 It's seem this seven function little complicate.You mean you understand it all? – yode Jan 22 '17 at 21:18
• I have no need to understand it all, but I can read, if ever I need them. But it seems they are under development (see comments to my answer), so I probably won't base code on them at this point. At least not code that I expect to use more than once. (Stuff in GeneralUtilities  sometimes changes.) – Michael E2 Jan 22 '17 at 21:25

## 1 Answer

Such functions set up a one-time iterator, i.e. a GeneralUtilitiesIterator. Its functionality may be inspected with

? GeneralUtilitiesIterator


and so forth. Except for a ConstantIterator which always returns the same value (forever), they go sequentially through values until they return GeneralUtilitiesIteratorExhausted.

The main (if internal) utility is GeneralUtilitiesPackageScopePullIterator:

foo = GeneralUtilitiesKeyValueIterator[<|a -> x, b -> y, c -> z|>];

GeneralUtilitiesPackageScopePullIterator@foo
GeneralUtilitiesPackageScopePullIterator@foo
GeneralUtilitiesPackageScopePullIterator@foo
GeneralUtilitiesPackageScopePullIterator@foo
(*
a -> x
b -> y
c -> z
IteratorExhausted
*)


One can see from inspection with ?... that one can do such things as Map, Scan, Fold, Read, etc., over iterators:

foo = GeneralUtilitiesKeyValueIterator[<|a -> x, b -> y, c -> z|>];
Map[f, foo]
(*  {f[a -> x], f[b -> y], f[c -> z]}  *)


Normal converts them to a list:

foo = GeneralUtilitiesKeyValueIterator[<|a -> x, b -> y, c -> z|>];
Normal[foo]
(*  {a -> x, b -> y, c -> z}  *)


Other functionality can be inspected with ?.

• +1. It would appear that in V11 Map, Scan, Fold and Select are all eager. This limits the usefulness of iterators (e.g. Map[10 #&, ConstantIterator[3]] is a bad idea). I guess we'll need to wait for Leonid's streams to hit prime time :) Incidentally, Read is the analog of Python's next. – WReach Jan 22 '17 at 5:50
• @WReach 1. Does it matter for Fold? 2. I wish you had referenced your discussion at mathematica.stackexchange.com/questions/838/… – Alan Jan 22 '17 at 6:01
• @Alan No, it does not matter for Fold (I was thinking FoldList). I suppose Scan` is arguable as well since it is executed for side-effects. Neither would be a good idea on an infinite stream. – WReach Jan 22 '17 at 6:26
• +1, good exposure of internal stuff :). There is a hope that at some point soon iterators will get a standardized treatment in WL. – Leonid Shifrin Jan 22 '17 at 14:03
• @WReach Hopefully soon now. Have to say though, that LazyList / its iteration process is only coarse-grained lazy, and works in chunks, where operations within a single chunk are eager. This is done for performance, in the first place. The user can in principle control the chunk size, but setting it to 1 will lead to really large framework overhead. – Leonid Shifrin Jan 22 '17 at 14:05