tableUtils

29 July 2021 Link



Description

tableUtils is a module that provides a lot of useful utilities to manipulate Lua Tables.

Installation

There are 2 ways to install it:
  • The module consists of a single Lua file which can be placed in any path where Lua can find it through its package.path definition.
  • Or you can install it using Luarocks by running the command:
luarocks install tableUtils

Usage

To use the module simply do:
tu = require("tableUtils")
Now tu will contain all the functions available for table manipulation

API

Functions

t2s

To convert a non recursive table to a string value for storage
Syntax:
t2s((t: table)) -> (string)
Usage:
  1. tableString = t2s(t) -- t is a non recursive table

Inputs:
  • t is a non recursive table. A non recursive table is one where the table structure does not link to some of its own part. Any Lua table that can be written in the curly bracket format in 1 statement should work.

All metatables are ignored.
Keys and values that are:
  • Number
  • Boolean
  • Table
are maintained in the conversion rest everything is treated/converted to string.

Returns:
  • string representation of the table which can be executed by Lua to recreate the table later

t2spp

To convert a non recursive table to a string value for storage. The output is a table pretty printed in the string.
Syntax:
t2spp((t: table)) -> (string)
Usage:
  1. tableString = t2spp(t) -- t is a non recursive table

Inputs:
  • t is a non recursive table. A non recursive table is one where the table structure does not link to some of its own part. Any Lua table that can be written in the curly bracket format in 1 statement should work.

All metatables are ignored.
Keys and values that are:
  • Number
  • Boolean
  • Table
are maintained in the conversion rest everything is treated/converted to string.

Returns:
  • string representation of the table (pretty printed) which can be executed by Lua to recreate the table later

t2sr

To convert a table including recursive tables to a string value for storage
Syntax:
t2sr((t: table)) -> (string)
Usage:
  1. tableString = t2sr(t) -- t is a non recursive table

Inputs:
  • t is a table, can be recursive. A recursive table is one where the table structure links to some of its own part. The function does that by writing Lua code to recreate the table.
  • All metatables are ignored.

Keys and values that are:
  • Number
  • Boolean
  • Table
are maintained in the conversion rest everything is treated/converted to string.


Returns:
  • string representation of the table which can be executed by Lua to recreate the table later

s2t

To convert a string to a table which was converted to a string using the t2s or t2spp
Syntax:
s2t((s: string)) -> (table)
Usage:
  1. table = s2t(s) -- s is the string representation of the table created using t2s or t2spp

Inputs:
  • s is a string that was created using the t2s or t2spp functions

Returns:
  • table representation of the string.


s2tr

To convert a string to a table which was converted to a string using the t2sr
Syntax:
s2tr((s: string)) -> (table)
Usage:
  1. table = s2tr(s) -- s is the string representation of the table created using t2sr

Inputs:
  • s is a string that was created using the t2sr

Returns:
  • table representation of the string.

mergeArrays

To merge 2 arrays
Syntax:
mergeArrays((t1:Array),(t2:Array),(duplicates: boolean),(isduplicate:function)) -> (t2:table)
Usage
  1. t2 = mergeArray(t1,t2,false,function(one,two) return one == two end)

Inputs:
  • t1 is a first array to merge to the second array
  • t2 is the second array
  • duplicates is a boolean which when false then duplicates are removed
  • isduplicate [OPTIONAL] is a function that when passed 2 members the 1st from t1 and the second from t2 returns true when they are duplicate.

Returns:
  • table t2 with elements from t1 merged into it

inArray

To find whether an array contains an element
Syntax:
inArray((t:table),(v:any),[(equal:function)])) -> (boolean)
Usage
  1. inArray(t,v,function(one,v) return one == v end)

Inputs
  • t is an array
  • v is a value that has to be checked if it exists in the t array
  • equal [OPTIONAL] is a function which when passed 2 vales the 1st from t and the second v returns true if the 1st value verifies existence of v in t

Returns:
  • true or false depending on whether v exists in t according to equal

emptyTable

To empty a table
Syntax
emptyTable((t:table)) -> (true)

Usage
  1. emptyTable(t)

Inputs
  • t is a table that needs to be emptied

Returns:
  • true


emptyArray

To empty an array
Syntax
emptyArray((t:array)) -> (true)

Usage
  1. emptyArray(t)

Inputs
  • t is an array that needs to be emptied

Returns:
  • true

isRecursive

To check whether a table is recursive. A recursive table is one where the table structure links to some of its own part.
Syntax
isRecursive(t)->(boolean)
Usage
  1. isRecursive(t)

Inputs
  • t is a table that needs to be checked if it is recursive

Returns
  • true if table is recursive else false

copyTable

To copy a table to another table. The table being copied and the recursive structure will be recreated.
Syntax
copyTable(t1,t2,full)->(t2:table),(map:table)
Usage
  1. t2,map = copyTable(t1,t2,true)

Inputs
  • t1 is a table that needs to be copied to t2
  • t2 is the destination table
  • full if true then copy is recursively going down into nested tables

Returns
  • t2 table with t1 copied in it
  • map a table which provides a mapping of the tables in t1 to the copy tables in t2 in map.s2d and vice versa in map.d2s

compareTables

To compare 2 tables. The tables can be recursive and it will compare the recursive structure as well.
Syntax
compareTables(t1,t2)->(boolean)
Usage
  1. compareTables(t1,t2)

Inputs
  • t1 is table 1
  • t2 is table 2

Returns
  • true if tables are same values and structure
  • nil if not same

diffTable

Function to return the diff patch of t2-t1. The patch when applied to t1 will make it equal in value to t2 such that compareTables will return true. The patch can be applied with the patch function.
Syntax
diffTable((t1:table),(t2:table),(map:table)) -> (patch:table)
Usage
  1. patch = diffTable(t1,t2,map)

Inputs
  • t1 is table 1
  • t2 is table 2
  • map is a mapping of of any table in t2 to a table in t1, i.e. they can be considered referring to the same table. In other words:
    • if map[x] = y where type(x) = type(y) = table and
    • x is a table that exists in the hierarchy of t2 and
    • y is a table that exists in the hierarchy of t1
      Then when the patch is generated it will be such that when it is applied it will turn y equivalent to x such that compareTables on them will return true

Returns
patch table which can be applied to t1 to make it the same (according to compareTables) to t2.

Example
An example where this is useful is to track/undo/redo table changes without storing a copy of the table again and again.
Suppose we have a table t1 and we want to keep a track of the changes in a table called changes. We can do this as follows:
  1. -- Before the change make a copy of the table
  2. t2,map = copyTable(t1,{},true)
  3. -- Do the table t1 manipulation here
  4. ...
  5. -- Now calculate the diff of the change
  6. changes[#changes + 1] = diffTable(t1,t2,map.d2s)

The above code when repeated will keep track of all changes done as diff patches stored in changes sequentially. If we need to roll back the changes then we simply do the following:
  1. patch(t1,changes[#changes])
  2. changes[#changes] = nil

The above code when repeated will undo the changes done on t1 sequentially. When #changes==0 then t1 will be the same as when we started before any changes.

patch

Function to patch table t with the diff provided to convert it to the next table. The diff should be generated by the diffTable function. patch is the inverse of the diffTable function such that compareTables will consider them the same tables.

Syntax
patch((t:table),(diff:table)) -> (t:table)

Usage
  1. t = patch(t,diff)


Inputs
  • t table on which to apply the patch
  • diff table generated from diffTable function

Returns
  • t table after the patch is applied


Repository

The repository can be found on github