Table Utilities

Utility functions that deal specifically with tables.

Summary
Table UtilitiesUtility functions that deal specifically with tables.
otlib
A Discussion On fori
CountCounts the number of elements in a table using pairs.
IsEmptyChecks if a table contains any values on any type of key.
EmptyRemoves all data from a table.
CopyMake a shallow copy of a table.
CopyIExactly the same as Copy except that it uses fori instead of pairs.
DeepCopyMake a deep copy of a table.
RemoveDuplicateValuesRemoves any duplicate values from a list.
UnionByKeyMerges two tables by key.
UnionByKeyIExactly the same as UnionByKey except that it uses fori instead of pairs.
UnionByValueGets the union of two lists by value.
IntersectionByKeyGets the intersection of two tables by key.
IntersectionByKeyIExactly the same as IntersectionByKey except that it uses fori instead of pairs.
IntersectionByValueGets the intersection of two lists by value.
DifferenceByKeyGets the difference of two tables by key.
DifferenceByKeyIExactly the same as DifferenceByKey except that it uses fori instead of pairs.
DifferenceByValueGets the difference of two lists by value.
AppendAppends values with numeric keys from one table to another.
HasValueChecks for the presence of a value in a table.
HasValueIExactly the same as HasValue except that it uses fori instead of pairs.
Table Conversion UntilitiesConvert tables between one thing and another!
SetFromListCreates a set from a list.
MakeKeyValuesMakes a key values string from a table.
ParseKeyValuesParses a key value formatted string into a table.

otlib

Summary
A Discussion On fori
CountCounts the number of elements in a table using pairs.
IsEmptyChecks if a table contains any values on any type of key.
EmptyRemoves all data from a table.
CopyMake a shallow copy of a table.
CopyIExactly the same as Copy except that it uses fori instead of pairs.
DeepCopyMake a deep copy of a table.
RemoveDuplicateValuesRemoves any duplicate values from a list.
UnionByKeyMerges two tables by key.
UnionByKeyIExactly the same as UnionByKey except that it uses fori instead of pairs.
UnionByValueGets the union of two lists by value.
IntersectionByKeyGets the intersection of two tables by key.
IntersectionByKeyIExactly the same as IntersectionByKey except that it uses fori instead of pairs.
IntersectionByValueGets the intersection of two lists by value.
DifferenceByKeyGets the difference of two tables by key.
DifferenceByKeyIExactly the same as DifferenceByKey except that it uses fori instead of pairs.
DifferenceByValueGets the difference of two lists by value.
AppendAppends values with numeric keys from one table to another.
HasValueChecks for the presence of a value in a table.
HasValueIExactly the same as HasValue except that it uses fori instead of pairs.
Table Conversion UntilitiesConvert tables between one thing and another!
SetFromListCreates a set from a list.
MakeKeyValuesMakes a key values string from a table.
ParseKeyValuesParses a key value formatted string into a table.

A Discussion On fori

We define fori as the following type of loop where t is the table you’re iterating over

for i=1, #t do body end

fori is much faster than pairs when you’re iterating over a table with only numeric keys.  The catch is that it must be sequential numeric keys starting at 1.  Even with this restriction, it is still very much worthwhile to use fori to iterate over the table instead of pairs if you have a table that meets the requirements to use fori.

Because of all this, OTLib lets you make a choice between using pairs or fori on anything that would make sense to have the choice.  Any function that has the same name as another function but is just suffixed with the character “I” uses fori where the function that is not suffixed uses pairs as its iterator.  For example, Copy and CopyI.  One should use CopyI instead of Copy whenever the table being copied is known to be a list-like table with sequential numeric keys starting at 1.

A quirk with a simple fori iteration is that you might pick up “gaps” in the table where the keys are not all sequential, but continues on with a later key anyways.  Ideally, you shouldn’t be passing around data like that unless you have a really good reason, but to partially combat this issue our code that uses fori on tables generally looks like the following:

for i=1, #t do
    if t[ i ] ~= nil then
        body
    end
end

This prevents us from working with empty slots in the table.  However, keep in mind that the way Lua implements tables means that if you have gaps in your table, a fori loop might not pick up all that data you want it to.

Count

function Count(t)

Counts the number of elements in a table using pairs.

Parameters

tThe table to count.

Returns

The number of elements in the table.

Example

Count( { "apple", "pear", done=true, banana="yellow" } )

returns...

4

Notes

  • This is slow and should be avoided if at all possible.
  • Use the ‘#’ operator instead of this if the table only contains numeric indices or if you you only care about the numeric indices.
  • Use IsEmpty instead of this if you only want to see if a hash table has any values.
  • Complexity is O( n ), where n is the number of values in t.

Revisions

v1.00Initial.

IsEmpty

function IsEmpty(t)

Checks if a table contains any values on any type of key.

Parameters

tThe table to check.

Returns

A boolean, true if the table t has one or more values, false otherwise.

Notes

  • This is much faster than Count for checking if a table has any elements, but you should still use the ‘#’ operator instead of this if you only care about numeric indices.
  • Complexity is O( 1 ).

Revisions

v1.00Initial.

Empty

function Empty(t)

Removes all data from a table.

Parameters

tThe table to empty.

Returns

The table t.

Notes

  • Complexity is O( Count( t ) ).

Revisions

v1.00Initial.

Copy

function Copy(t)

Make a shallow copy of a table.  A shallow copy means that any subtables will still refer to the same table.

Parameters

tThe table to make a copy of.

Returns

The copied table.

Notes

  • Complexity is O( Count( t ) ).

Revisions

v1.00Initial.

CopyI

function CopyI(t)

Exactly the same as Copy except that it uses fori instead of pairs.  In general, this means that it only copies numeric keys.  See A Discussion On fori.

DeepCopy

function DeepCopy(t)

Make a deep copy of a table.  A deep copy means that any subtables will refer to a new copy of the original subtable.

Parameters

tThe table to make a copy of.  Must not have any cycles.

Returns

The copied table.

Revisions

v1.00Initial.

RemoveDuplicateValues

function RemoveDuplicateValues(list,
in_place)

Removes any duplicate values from a list.

Parameters

listThe list table to remove duplciates from.
in_placeAn optional boolean specifying whether or not the deletions should be done in place to table_a.  Defaults to false.

Returns

The list table with duplicates removed.  Returns t if in_place is true, a new table otherwise.

Example

RemoveDuplicateValues( { "apple", "pear", "kiwi", "apple", "banana", "pear", "pear" } )

returns...

{ "apple", "pear", "kiwi", "banana" }

Notes

  • This function operates over numeric indices.  See A Discussion On fori.
  • Complexity is around O( #t * log( #t ) ).
  • Duplicates are removed after the first value occurs.  See example above.

Revisions

v1.00Initial.

UnionByKey

function UnionByKey(table_a,
table_b,
in_place)

Merges two tables by key.

Parameters

table_aThe first table in the union.  If in_place is true, all operations occur on this table, if in_place is false, all operations occur on a copy of the table.
table_bThe second table in the union.
in_placeAn optional boolean specifying whether or not this should be an in place union to table_a.  Defaults to false.

Returns

The union table.  Returns table_a if in_place is true, a new table otherwise.

Example

UnionByKey( { apple="red", pear="green", kiwi="hairy" },
       { apple="green", pear="green", banana="yellow" } )

returns...

{ apple="green", pear="green", kiwi="hairy", banana="yellow" }

Notes

  • If both tables have values on the same key, table_b takes precedence.
  • Complexity is O( Count( table_b ) ).

Revisions

v1.00Initial.

UnionByKeyI

function UnionByKeyI(table_a,
table_b,
in_place)

Exactly the same as UnionByKey except that it uses fori instead of pairs.  In general, this means that it only merges on numeric keys.  See A Discussion On fori.

UnionByValue

function UnionByValue(list_a,
list_b,
in_place)

Gets the union of two lists by value.  If a value occurs once in list_a and once in list_b, the result of the union will only occur one instance of that value as well.

Parameters

list_aThe first list table in the union.  If in_place is true, all operations occur on this table, if in_place is false, all operations occur on a copy of the table.
list_bThe second list table in the union.
in_placeAn optional boolean specifying whether or not this should be an in place union to table_a.  Defaults to false.

Returns

The union list table.  Returns table_a if in_place is true, a new table otherwise.

Example

UnionByValue( { "apple", "pear", "kiwi" }, { "pear", "apple", "banana" } )

returns...

{ "apple", "pear", "kiwi", "banana" }

Notes

  • This function operates over numeric indices.  See A Discussion On fori.
  • The elements that in the returned table are in the same order they were in table_a and then table_b.  See example above.
  • This function properly handles duplicate values in either list.  All values will be unique in the resulting list.
  • Complexity is O( #table_a * #table_b ), so you might want to consider using SetFromList combined with UnionByKey for large tables or if you plan on doing this often.

Revisions

v1.00Initial.

IntersectionByKey

function IntersectionByKey(table_a,
table_b,
in_place)

Gets the intersection of two tables by key.

Parameters

table_aThe first table in the intersection.  If in_place is true, all operations occur on this table, if in_place is false, all operations occur on a copy of the table.
table_bThe second table in the interesection.
in_placeAn optional boolean specifying whether or not this should be an in place intersection to table_a.  Defaults to false.

Returns

The intersection table.  Returns table_a if in_place is true, a new table otherwise.

Example

IntersectionByKey( { apple="red", pear="green", kiwi="hairy" },
       { apple="green", pear="green", banana="yellow" } )

returns...

{ apple="green", pear="green" }

Notes

  • If both tables have values on the same key, table_b takes precedence.
  • Complexity is O( Count( table_a ) ).

Revisions

v1.00Initial.

IntersectionByKeyI

function IntersectionByKeyI(table_a,
table_b,
in_place)

Exactly the same as IntersectionByKey except that it uses fori instead of pairs.  In general, this means that it only merges on numeric keys.  See A Discussion On fori.

IntersectionByValue

function IntersectionByValue(list_a,
list_b,
in_place)

Gets the intersection of two lists by value.

Parameters

list_aThe first list table in the intersection.  If in_place is true, all operations occur on this table, if in_place is false, all operations occur on a copy of the table.
list_bThe second list table in the interesection.
in_placeAn optional boolean specifying whether or not this should be an in place intersection to table_a.  Defaults to false.

Returns

The intersection list table.  Returns table_a if in_place is true, a new table otherwise.

Example

IntersectionByValue( { "apple", "pear", "kiwi" }, { "pear", "apple", "banana" } )

returns...

{ "apple", "pear" }

Notes

  • This function operates over numeric indices.  See A Discussion On fori.
  • The elements that are left in the returned table are in the same order they were in table_a.  See example above.
  • This function properly handles duplicate values in either list.  All values will be unique in the resulting list.
  • Complexity is O( #table_a * #table_b ), so you might want to consider using SetFromList combined with IntersectionByKey for large tables or if you plan on doing this often.

Revisions

v1.00Initial.

DifferenceByKey

function DifferenceByKey(table_a,
table_b,
in_place)

Gets the difference of two tables by key.  Difference is defined as all the keys in table A that are not in table B.

Parameters

table_aThe first table in the difference.  If in_place is true, all operations occur on this table, if in_place is false, all operations occur on a copy of the table.
table_bThe second table in the difference.
in_placeAn optional boolean specifying whether or not this should be an in place difference operation on table_a.  Defaults to false.

Returns

The difference table.  Returns table_a if in_place is true, a new table otherwise.

Example

DifferenceByKey( { apple="red", pear="green", kiwi="hairy" },
            { apple="green", pear="green", banana="yellow" } )

returns...

{ kiwi="hairy" }

Notes

  • Complexity is O( Count( table_a ) ).

Revisions

v1.00Initial.

DifferenceByKeyI

function DifferenceByKeyI(table_a,
table_b,
in_place)

Exactly the same as DifferenceByKey except that it uses fori instead of pairs.  In general, this means that it only performs the difference on numeric keys.  See A Discussion On fori.

DifferenceByValue

function DifferenceByValue(list_a,
list_b,
in_place)

Gets the difference of two lists by value.

Parameters

list_aThe first list table in the difference.  If in_place is true, all operations occur on this table, if in_place is false, all operations occur on a copy of the table.
list_bThe second list table in the difference.
in_placeAn optional boolean specifying whether or not this should be an in place difference operation on table_a.  Defaults to false.

Returns

The difference list table.  Returns table_a if in_place is true, a new table otherwise.

Example

DifferenceByValue( { "apple", "pear", "kiwi" }, { "pear", "apple", "banana" } )

returns...

{ "kiwi" }

Notes

  • This function operates over numeric indices.  See A Discussion On fori.
  • The elements that are left in the returned table are in the same order they were in table_a.  See example above.
  • This function properly handles duplicate values in either list.  All values will be unique in the resulting list.
  • Complexity is O( #table_a * #table_b ), so you might want to consider using SetFromList combined with DifferenceByKey for large tables or if you plan on doing this often.

Revisions

v1.00Initial.

Append

function Append(list_a,
list_b,
in_place)

Appends values with numeric keys from one table to another.

Parameters

list_aThe first list table in the append.  If in_place is true, table_b is appended to this table.  Values in this table will not change.
list_bThe second list table in the append.
in_placeAn optional boolean specifying whether or not this should be an in place append to table_a.  Defaults to false.

Returns

The table result of appending table_b to table_a.  Returns table_a if in_place is true, a new table otherwise.

Example

Append( { "apple", "banana", "kiwi" },
        { "orange", "pear" } )

returns...

{ "apple", "banana", "kiwi", "orange", "pear" }

Notes

Revisions

v1.00Initial.

HasValue

function HasValue(t,
value)

Checks for the presence of a value in a table.

Parameters

tThe table to check for the value’s presence within.
valueAny type, the value to check for within t.

Returns

1A boolean.  True if the table has the value, false otherwise.
2A value of any type.  The first key the value was found under if it was found, nil otherwise.

Example

HasValue( { apple="red", pear="green", kiwi="hairy" }, "green" )

returns...

true, "pear"

Revisions

v1.00Initial.

HasValueI

function HasValueI(t,
value)

Exactly the same as HasValue except that it uses fori instead of pairs.  In general, this means that it only merges on numeric keys.  See A Discussion On fori.

Table Conversion Untilities

Convert tables between one thing and another!

SetFromList

function SetFromList(list)

Creates a set from a list.  A list is defined as a table with all numeric keys in sequential order (such as {“red”, “yellow”, “green”}).  A set is defined as a table that only uses the boolean value true for keys that exist in the table.  This function takes the values from the list and makes them the keys in a set, all with the value of ‘true’.  Note that you lose ordering and duplicates in the list during this conversion, but gain ease of testing for a value’s existence in the table (test whether the value of a key is true or nil).

Parameters

listThe table representing the list.

Returns

The table representing the set.

Example

SetFromList( { "apple", "banana", "kiwi", "pear" } )

returns...

{ apple=true, banana=true, kiwi=true, pear=true }

Notes

  • This function uses fori during the conversion process.  See A Discussion On fori.
  • Complexity is O( #list )

Revisions

v1.00Initial.

MakeKeyValues

function MakeKeyValues(t)

Makes a key values string from a table.

Parameters

tThe table to make the key values from.  The table’s keys and subkeys may be of string or number type.  The table’s values and subvalues may be of string, number, boolean, or table types.  Do not pass in a cyclical table or this function will error.

Returns

The key values string.

Example

{ 3.14, "foo", bar = { pear = "green", t = { none = 0 } } }

returns...

"bar"
{
        "t"
        {
                "none"  0
        }
        "pear"  "green"
}
3.14
"foo"

Notes

  • This function attempts to simplify list-like tables by not including the key on coherent lists.  The key in a list is implied by the order the value comes in.
  • The list portion of a table will always be output after the hash portion of a table.
  • Although cyclical tables can’t be used in this function, tables with joins can.  The joins will be copied and treated as separate but identical tables when deserialized.
  • Subtables are not allowed to be indexed by a number.  This restriction is to avoid creating an ambiguity in the grammar.

Revisions

v1.00Initial.

ParseKeyValues

function ParseKeyValues(str)

Parses a key value formatted string into a table.  See MakeKeyValues for creating a key value string.

Parameters

strThe string to parse.

Returns

1The table on success or nil on failure.
2Nil on success, or the string explaining the error on failure.

Revisions

v1.00Initial.
function Count(t)
Counts the number of elements in a table using pairs.
function IsEmpty(t)
Checks if a table contains any values on any type of key.
function Empty(t)
Removes all data from a table.
function Copy(t)
Make a shallow copy of a table.
function CopyI(t)
Exactly the same as Copy except that it uses fori instead of pairs.
function DeepCopy(t)
Make a deep copy of a table.
function RemoveDuplicateValues(list,
in_place)
Removes any duplicate values from a list.
function UnionByKey(table_a,
table_b,
in_place)
Merges two tables by key.
function UnionByKeyI(table_a,
table_b,
in_place)
Exactly the same as UnionByKey except that it uses fori instead of pairs.
function UnionByValue(list_a,
list_b,
in_place)
Gets the union of two lists by value.
function IntersectionByKey(table_a,
table_b,
in_place)
Gets the intersection of two tables by key.
function IntersectionByKeyI(table_a,
table_b,
in_place)
Exactly the same as IntersectionByKey except that it uses fori instead of pairs.
function IntersectionByValue(list_a,
list_b,
in_place)
Gets the intersection of two lists by value.
function DifferenceByKey(table_a,
table_b,
in_place)
Gets the difference of two tables by key.
function DifferenceByKeyI(table_a,
table_b,
in_place)
Exactly the same as DifferenceByKey except that it uses fori instead of pairs.
function DifferenceByValue(list_a,
list_b,
in_place)
Gets the difference of two lists by value.
function Append(list_a,
list_b,
in_place)
Appends values with numeric keys from one table to another.
function HasValue(t,
value)
Checks for the presence of a value in a table.
function HasValueI(t,
value)
Exactly the same as HasValue except that it uses fori instead of pairs.
function SetFromList(list)
Creates a set from a list.
function MakeKeyValues(t)
Makes a key values string from a table.
function ParseKeyValues(str)
Parses a key value formatted string into a table.
Close