Iterator

Lua’s built-in iterator mechanism is clumsy at best, with the documentation even admitting they “may be difficult to write, but are easy to use.” While they are easy to use when called directly within a for loop, they are not easy to pass around, explicitly document functions which return them, or extend the functionality of. The Iterator module intends to address these shortfalls and provide some additional functionality.

Example

Below is an example which shows all the feature of the iterator objects.

local MyModule = select(2, ...).MyModule
local Iterator = MyModule:From("LibTSMUtil"):Include("BaseType.Iterator")

local iter = Iterator.Acquire(ipairs({"a", 23, 17, "c"}))
   :Filter(function(index, value) return type(value) == "string" end)
   :SetMapFunc(function(index, value) return value, string.upper(value) end)
for i, str, upperStr in iter do
   print(i, str, upperStr)
end
-- 1    a    A
-- 4    c    C

print(Iterator.Acquire(ipairs({1, 2, 3})):ToJoinedValueString(",")) -- 1,2,3

Memory Management

The lifecycle of iterator objects is owned by the Iterator module. They are acquired via the Iterator.Acquire() function and its up to the caller to ensure they are properly released back to the Iterator module for recycling. In most cases, this is done automatically by simply running the iteration all the way to completion. For cases where breaking out of the iterator early is required, the application must explicitly call the :Release() method on the iterator object.

API

class BaseType.Iterator: LibTSMModule
staticmethod Acquire(
    func: fun(obj?: <T>, key: <K>, ...any): ...unknown,
    obj?: <T>,
    key?: <K>,
    ...: any
): IteratorObject

Acquires an Iterator object which wraps the passed iterator function.

Parameters:
  • func (fun(obj?: <T>, key: <K>, ...any): ...unknown) – The iterator function

  • obj? (<T>) – The object being iterated over

  • key? (<K>) – The initial key for the iterator function

  • ... (any) – Additional arguments to pass to the iterator function

staticmethod AcquireEmpty(): IteratorObject | fun()

Acquires an Iterator object which does not produce any values.

class IteratorObject
Filter(self: IteratorObject, func: IteratorFilterFunc): IteratorObject

Adds a function to filter iterator values (happens before mapping).

Parameters:

func (IteratorFilterFunc) – Function which returns if a value should be provided by the iterator

SetMapFunc(self: IteratorObject, func: IteratorMapFunc): IteratorObject

Sets a function to map iterator values (happens after filtering).

Parameters:

func (IteratorMapFunc) – Function used to map iterator values (the key cannot be mapped and shouldn’t be returned)

SetCleanupFunc(self: IteratorObject, func: fun(obj: any)): IteratorObject

Sets a function called when the iterator is released to clean up any associated context.

Parameters:

func (fun(obj: any)) – The cleanup function which is passed the original iterator object

GetValueAndRelease(self: IteratorObject): (...: any)

Get the next value and release the iterator.

ToJoinedValueString(self: IteratorObject, sep: string, sorted?: boolean): string

Evaluates the iterator and returns the result as a joined string of all the values.

Parameters:
  • sep (string) – The separator

  • sorted? (boolean) – Whether or not to sort the values before concatenating it

Release(self: IteratorObject)

Releases the iterator.