Iterator Pattern


Problem


Need to be able to traverse diverse data structures in a common abstract way.

Solution


The main principle is to take the responsibility for access and traversal out of the data structure and put that into an Iterator object.

Related Patterns


  • Visitor
  • Composite
  • Memento (Iterators can store the current position as a Memento)
  • Factory (to instantiate appropriate subclasses if uncommon types are used)

Discussion


Iterators are fundamental to "generic programming", which seeks to boost productivity by reducing configuration costs.

Examples


A real-world example is the seek button on a radio. Though you may know the frequency of several stations, you may want to simply get to the next one. The seek button iterates to the next available station.

Code


Generally, iterators keep track of where it is in the structure. In Lua, the generic for loop keeps track of that. Though the iterator is often tricky to write, the use of that iterator is very easy.

function allwords ()
  local line = io.read()  -- current line
  local pos = 1           -- current position in the line
  return function ()      -- iterator function
    while line do         -- repeat while there are lines
      local s, e = string.find(line, "%w+", pos)
      if s then           -- found a word?
        pos = e + 1       -- next position is after this word
        return string.sub(line, s, e)     -- return the word
      else
        line = io.read()  -- word not found; try next line
        pos = 1           -- restart from first position
      end
    end
    return nil            -- no more lines: end of traversal
  end
end

for word in allwords() do
  print(word)
end