The transforms library is set of utilities for working with indexed tables. It provides highly reusable special iterators that are at the core of text and sh command parsing.

Transforms API

  • Transforms work on sequences

    All transforms methods expect to iterate over sequences, see

  • first and last

    All first and last arguments act in the same fashion as the first and last arguments used in string methods such as string.sub. That is, it accepts negative values, which work relative from the end. first (when optional) defaults to 1, and last defaults to -1.

  • The Predicate

    All transform methods that take a predicate use this predicate defintiion:

    • predicate(element: value, index: number, tbl: table): number, number

      This predicate is called in sequence on each index in tbl. element is the value at tbl[index]. Generally, predicate methods ignore index and tbl, and only process element. But some predicates may need to check values in tbl before or after index. Important to note that the tbl passed to the predicate is actually a view of the original table passed to the transforms api. This view is not a natural sequence but instead only returns values from tbl within the [first, last] range.

      In other words, the predicate handles a “set of elements” and returns parameters indicating the satisfied condition.

      • Set of Elements

        The “set of elements” refers to either:

        A) The single element passed to the predicate. This is the same value at tbl[index]


        B) The sequence of elements starting at index in tbl. The predicate may iterate from index for as many elements it needs to check, until #tbl

      • Return Parameters

        Possible values for the return parameters 1 false or nil if the predicate is not satisfied with the set of elements. index to indicate success. It should simply return the same index given, which is the starting index of the set of elements 2. The size of the set of elements that satisfied the predicate, or nil Some tranform methods may specify that the 2nd return is optional, such as transforms.first()

        Some transform methods may specify alternative predicate types that can be used, such as tables or strings. These predicate usages are specific to those methods and defined within the method details here.


  • transforms.sub(tbl: table, first: number, last: number or nil): table

    Behaves similarly to string.sub. Returns a sub table of tbl from first to last.

  • transforms.first(tbl: table, predicate: function or table, first: number or nil, last: number or nil): number, number

    Returns the first index in tbl (between indexes first and last, inclusively) where predicate is satisfied. The 2nd return is also the ending index of the match. General examples will have the same two values returned, i.e. a match of length 1. The predicate can (optionally) return a 2nd return value to indicate the size of the match.

    In the case that predicate is a table, transforms.first() returns the starting and ending index of the first matching sub table in tbl that matches ANY one of the tables in predicate.


local tx = require("transforms")
print( tx.first ( { 1, 1, 3, 2, 4, 7 }, function(e, i, tbl)
  local evens = 0
  for i=i,#tbl do
    if tbl[i] % 2 == 0 then
      evens = evens + 1
  return evens > 0, evens


4  5
local tx = require("transforms")
print( tx.first ( { 1, 1, 3, 2, 4, 7 }, { {1, 2}, {3, 2, 4} }) )


3  5
  • transforms.partition(tbl: table, partioner: function, first: number or nil, last: number or nil): table of tables

    Returns a list of sub lists from tbl, generated by partioner within the range from first to last. partioner is a predicate function, defined above.

    The index parameter passed to the partitioner will skip ranges, i.e. it will increase by n where n is the size of the partition.

    The partitioner predicate for this method must return the starting AND ending index of satisfied element sets. Again, see the predicate info above.

  • transforms.begins(tbl: table, sub: table, first: number or nil, last: number or nil)

    Returns true if the subset of tbl from first to last fully composes v aligned at the first index. Assuming first and last have been adjusted for negative wrap around, that is to say:

    v[1] == tbl[first + 0]

    v[2] == tbl[first + 1]

    v[#v] == tbl[first + #v - 1]

    Where first + #v - 1 is within the bounds of [first, last] of tbl.

  • transforms.foreach(tbl: table, adapter: function, first: number or nil, last: number or nil)

    Returns an adaptation of each element in tbl from first to last. Any nil result of the adapter is ignored, and not appended to the result.
    The adapter follows the predicate signature except for the handling of the return values

    • Adapter Returns

      The simple case is to return a single value. E.g. tx.foreach({'a', 'b', 'c'}, string.upper) would return {'A', 'B', 'C'}.
      The adapter can return nil to skip a value. E.g. tx.foreach({'1', 'foobar', '2'}, function(n) return tonumber(n) end) would return {1, 2}.

      But the adapter can return a second value that is used in place of the next sequence number. E.g. tx.foreach({'1','foobar','3'},function(n,i) return tonumber(n), tostring(i) end) would return {["1"]=1, ["3"]=3}