Module Table
Table manipulation.
Note: This module inherits all native-Lua table module methods unless overwritten by same-named local methods.
Module Status: Stable.
Usage:
local Table = require('__eradicators-library__/erlib/lua/Table')()
Module
Table(tbl) | Attaches this Table module as metatable to a table. |
NIL | Workaround to put |
Basic Methods
size(tbl) | Counts (key → value) pairs. |
array_size(tbl) | The largest numeric key in the array part of this table. |
range([a=1], b[, step]) | Generates a DenseArray of NaturalNumbers. |
values(tbl) | Generates an unsorted DenseArray from the values of tbl. |
keys(tbl) | Generates an unsorted DenseArray from the keys of tbl. |
flip(tbl) | Creates a new table in which (key ↔ value) mappings are swapped. |
plural(obj) | Wraps the object in a table if it is not already a table. |
is_equal(tbl, tbl2) | Deep compare. If two tables have exactly the same content. |
is_empty(tbl) | Returns true if the table contains no values. |
nil_if_empty(tbl) | Converts empty tables into a nil value. |
Search Methods
find_largest(tbl[, gtr]) | Finds the largest element in a table. |
find(tbl, value) | Retrieves the key of a value. |
next_value(tbl[, key=nil]) | Fetches the next value in a table. |
first_value(tbl) | Shortcut to Table.next_value(tbl,nil) that doesn't return the key at all. |
In-Place Methods
pop(tbl, key[, value=nil]) | In-place. Removes a (key → value) pair and returns the value. |
map(tbl, f[, target=nil]) | In-place. Applies a function to all elements of a table. |
filter(tbl, f[, target=nil]) | In-place. Removes elements from a table based on a filter function. |
smerge(tbl[, tbl2]) | In-place. Shallow Merge. Copies data from one table into another. |
insert_once(tbl, key, value) | In-place. Inserts value into tbl only if no other key in the table has an == equal value. |
clear(tbl, except_keys[, is_whitelist=true]) | In-place. Removes all key→value mappings from a table. |
overwrite(table_reference, value_table) | In-place. Puts the content of one table into the reference of another. |
migrate(tbl, index, migrations[, ...]) | In-place. Applies a series of migration functions to sub-table. |
Copy Methods
scopy(tbl) | Shallow Copy. Copies the first level of the table such that all sub-table references stay identical to the original table. |
dcopy(tbl[, remove_metatables=false]) | Deep Copy. A copy of a table that shares none of the original table references but has the same self-referencing structure. |
fcopy(tbl[, remove_metatables=false]) | Full Copy. A copy of a table that shares none of the original table references and in which all formerly self-referenced sub-tables are made unique. |
Other Methods
rep(tbl[, variation_count[, patterns]]) | Creates patterned and unpatterened table repetitions. |
remove_nil(tbl) | In-place. Shallowly replaces Table.NIL keys and values with nil, deleting the affected mappings. |
Conversion
to_array(tbl[, target=nil]) | In-place. Converts MixedTable to SparseArray. |
to_string(tbl) | Alias of String.to_string. |
Metamethods
__concat() | Addition with + is Table.smerge(). |
set_metamethod(tbl, method_name, f) | Set a function as metamethod of tbl. |
get_metamethod(tbl, method_name) | Gets the metamethod handler function of tbl. |
deep_clear_metatables(tbl) | Recursively removes metatables from all subtables but not from other object types. |
clear_meta(tbl) | Removes any metatable from a table. |
popmetatable(tbl) | Removes and returns the metatable. |
Path Methods
TablePath | Concept. A DenseArray of values that represent keys of a nested path in another table. |
get(tbl, path[, default=nil]) | Get the value at location path in tbl. |
set(tbl, path, value) | Set a new value to location path in tbl. |
sget(tbl, path, default) | Get the value at location path in tbl if it exists, otherwise creates it. |
add(tbl, path, number) | Adds a number to an existing value or creates a new value. |
remove(tbl, path) | Removes and returns a value from a table. |
TablePatch | Concept. A DenseArray consisting of a TablePath followed by a TablePatchValue. |
TablePatchValue | Concept. The value part of a TablePatch is not further interpreted unless it is a MixedTable made of a TablePath that contains the mapping {self=true} . |
patch(tbl, patches) | Takes an array of patches and applies them to a table. |
Factories
normalizer(defaults) | Factory. Applies default values to tables. |
TableNormalizerFunction(tbl) | In-place. Applies enclosurized defaults. |
remapper(mappings[, allow_tables_as_keys=false]) | Factory. Moves values from one key to another. |
TableRemapperFunction(tbl) | In-place. Applies enclosurized re-mappings. |
Module
- Table(tbl)
-
Attaches this Table module as metatable to a table.
Alias forsetmetatable(tbl, {__index = Table})
.Parameters:
- tbl table
Returns:
-
table
The unchanged input table, now with metatable attached.
- NIL
-
Workaround to put
values into tables. Lua can not usually put nil as keys or values in tables because it treats those as not to be in the table in the first place. For situations where you need to put nil values into tables Erlib offers to use this unique string that certain functions like Table.remove_nil, Table.set or Table.patch will recognize as nil value.
Basic Methods
- size(tbl)
-
Counts (key → value) pairs. Uses factorio table_size when
available.
Parameters:
- tbl table
Returns:
-
NaturalNumber
The total number of keys in this table. Counts all
types of keys including numeric.
- array_size(tbl)
-
The largest numeric key in the array part of this table.
For DenseArrays
the length operator # is much faster.
Parameters:
- tbl MixedTable A table with a sparse array part.
Returns:
- range([a=1], b[, step])
-
Generates a DenseArray of NaturalNumbers.
Parameters:
- a NaturalNumber (default 1)
- b NaturalNumber The end of the range (inclusive).
- step NaturalNumber (optional)
Returns:
Usage:
print(Table.range(10)) > {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} print(Table.range(5,10)) > {5, 6, 7, 8, 9, 10} print(Table.range(2,44,4)) > {2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42}
- values(tbl)
-
Generates an unsorted DenseArray from the values of tbl.
Parameters:
- tbl table
Returns:
- keys(tbl)
-
Generates an unsorted DenseArray from the keys of tbl.
Parameters:
- tbl table
Returns:
- flip(tbl)
-
Creates a new table in which (key ↔ value) mappings are swapped.
Duplicate values will be mapped to the last key that references them
but due to the behavior of next it's undefind behavior which key that
will be. In factorio pairs is deterministic and it should thus be the
key that was added to the table last.
Parameters:
- tbl table
Returns:
-
table
A new flipped table.
Usage:
local my_table = {'a','b','c','c'} print(Table(my_table):flip():to_string()) > {a = 1, b = 2, c = 4} print(Hydra.lines(Table(defines.events):flip())) > { [0] = "on_tick" [1] = "on_gui_click", [2] = "on_gui_text_changed", [3] = "on_gui_checked_state_changed", [4] = "on_entity_died", [5] = "on_picked_up_item", ... }
- plural(obj)
-
Wraps the object in a table if it is not already a table.
Parameters:
- obj AnyValue
Returns:
-
Table
- is_equal(tbl, tbl2)
-
Deep compare. If two tables have exactly the same content.
Note: Does not compare the content of tables-as-keys.
Parameters:
Returns:
Usage:
local a = {1,2,3,4} local b = {5,6,7,8} local c = {'a','b','c','d'}; c[5] = c local test1 = {a=a,b={b=b,c={c=c}}} local test2 = {a=a,b={b=b,c={c=c}}} print(test1 == test2) > false print(Table.is_equal(test1,test2)) > true
- is_empty(tbl)
-
Returns true if the table contains no values.
Parameters:
- tbl table
Returns:
- nil_if_empty(tbl)
-
Converts empty tables into a nil value.
Parameters:
Returns:
Search Methods
- find_largest(tbl[, gtr])
-
Finds the largest element in a table.
Parameters:
- tbl table
- gtr function A comparitor function f(a,b)→boolean that returns true when a is larger than b. Defaults to a>b. (optional)
Returns:
- find(tbl, value)
-
Retrieves the key of a value.
Parameters:
Returns:
- next_value(tbl[, key=nil])
-
Fetches the next value in a table. Respects __pairs metamethod. Return
value order is reversed compared to lua next. By default will return
the first value of a table.
Parameters:
Returns:
- first_value(tbl)
-
Shortcut to Table.next_value(tbl,nil) that doesn't return the key at all.
Parameters:
- tbl table
Returns:
-
AnyValue
The value.
In-Place Methods
- pop(tbl, key[, value=nil])
-
In-place. Removes a (key → value) pair and returns the value.
Alternatively replaces the old value with a new value.
Does not change the order of the remaining elements.
Parameters:
Returns:
- map(tbl, f[, target=nil])
-
In-place. Applies a function to all elements of a table.
Experts only: Table.map in Copy Mode supports changing the key that a value is associated with. If f(value,key,tbl) returns two values then the first is the new value and the second is the new key. If it returns one value then the original key will be used. This check is done for each key→value pair seperately.
Parameters:
- tbl table
- f function The function f(value,key,tbl) that produces the new value for each key→value mapping in the table.
- target table Copy Mode. The result of the operation will be written to this table and tbl remains unchanged. (default nil)
Returns:
-
table
The input table.
- filter(tbl, f[, target=nil])
-
In-place. Removes elements from a table based on a filter function.
Parameters:
- tbl table
- f function If calling f(value,key,tbl) does not return truthy then the value will be removed from the table.
- target table Copy Mode. The result of the operation will be written to this table and tbl remains unchanged. (default nil)
Returns:
-
table
The input table.
- smerge(tbl[, tbl2])
-
In-place. Shallow Merge. Copies data from one table into another.
Copies only the first layer of the table. All sub-table references stay
identical.
Parameters:
Returns:
-
table
The input table.
- insert_once(tbl, key, value)
-
In-place. Inserts value into tbl only if no other key in the table
has an == equal value.
Parameters:
Returns:
-
table
The input table.
- clear(tbl, except_keys[, is_whitelist=true])
-
In-place. Removes all key→value mappings from a table.
Parameters:
- tbl table
- except_keys DenseArray These keys will not be deleted.
- is_whitelist boolean If set to false only the except_keys will be deleted. (default true)
Returns:
-
table
The now empty input table.
- overwrite(table_reference, value_table)
-
In-place. Puts the content of one table into the reference of another.
Used when you need to replace all content of a table, but need to keep
external references to the table intact.
Parameters:
- table_reference table All key→value mappings in this table will be deleted.
- value_table table All key→value mappings will be shallowly copied into table_reference.
Returns:
-
Table
The input table reference with the
Usage:
local my_table = {1,2,3} local also_my_table = my_table local my_values = {'a','b','c'} Table.overwrite(my_table,my_values) print(my_table:to_string()) > {"a", "b", "c"} print(my_table == my_values) > false print(my_table == also_my_table) -- all local references stay intact > true
- migrate(tbl, index, migrations[, ...])
-
In-place. Applies a series of migration functions to sub-table.
Parameters:
- tbl table
- index NotNil The index of the to-be-migrated subtable in tbl. If the index does not yet exist it will be initialized as an empty table.
- migrations SparseArray A group of to-be-sequentially-applied migration functions. Each function will be called f(tbl[index],index,tbl,...).
- ... AnyValue Arbitrary extra data that will be passed to each migration function. (optional)
Returns:
-
The
fully migrated subtable.
Usage:
local my_data = { ['Peter'] = { -- No version means _version=0 name = 'Peter', }, ['Paula'] = { -- _version is internally managed and should not be manually changed. _version = 1, value = 12, givenname = 'Paula', } } local my_migrations = { -- The number indicates that version this function *outputs* -- Usually you will only need (data). [1] = function(data) -- Rename old values. data.givenname = data.name data.name = nil -- Initialize newly implemented values. data.value = 0 -- _version can *NOT* be manually changed during a migration. data._version = 42 -- this has no effect end, -- But sometimes extra parameters are useful. [2] = function(data,index,tbl,bonus,superbonus) -- Migrations can completely reconstruct the table. tbl[index] = { gnam = data.givenname or index, val = data.value + bonus + (superbonus or 0) } end, } -- You can migrate old data. for k,_ in pairs(my_data) do Table.migrate(my_data,k,my_migrations,30) print(k,':',Table(my_data[k]):to_string()) end > Paula : {_version = 2, gnam = "Paula", val = 42} > Peter : {_version = 2, gnam = "Peter", val = 30} -- Or you can create new data. Table.migrate(my_data,'Alex',my_migrations,1,9000) -- with superbonus print('Alex :',Table(my_data['Alex']):to_string()) > Alex : {_version = 2, gnam = "Alex", val = 9001}
Copy Methods
- scopy(tbl)
-
Shallow Copy. Copies the first level of the table such that all
sub-table references stay identical to the original table.
Parameters:
- tbl AnyValue
Returns:
-
table
The new table.
- dcopy(tbl[, remove_metatables=false])
-
Deep Copy. A copy of a table that shares none of the original table
references but has the same self-referencing structure.
Parameters:
- tbl AnyValue
- remove_metatables boolean Removes metatables from tbl and all sub-tables. (default false)
Returns:
-
table
The new table.
- fcopy(tbl[, remove_metatables=false])
-
Full Copy. A copy of a table that shares none of the original table
references and in which all formerly self-referenced sub-tables are made
unique.
Mostly useful for visual inspection of complex tables.
Parameters:
- tbl AnyValue
- remove_metatables boolean Removes metatables from tbl and all sub-tables. (default false)
Returns:
-
table
The new table.
Other Methods
- rep(tbl[, variation_count[, patterns]])
-
Creates patterned and unpatterened table repetitions.
Either count or patterns or both must be given.
Parameters:
- tbl table
- variation_count NaturalNumber How many repetitions to create. Will use the length of the first patterned key if not given. (optional)
- patterns table A table that maps each key to a DenseArray of at least length variation_count. (optional)
Returns:
Usage:
-- Simple example. Patternless repetition. local test = Table.rep({1,2,3},3) print(Hydra.lines(test)) > { > {1, 2, 3}, > {1, 2, 3}, > {1, 2, 3} > }
-- Intermediate example. Patterned repetition. local test = Table.rep({},3,{name = {'Peter','Paula','Alex'}}) print(Hydra.lines(test)) > { > {name = "Peter"}, > {name = "Paula"}, > {name = "Alex"} > }
-- Advanced example. -- Creating a Gui.construct compatible layout for a simple calculator. local buttons = { 1 , 2 , 3 ,'+','-', 4 , 5 , 6 ,'*','/', 7 , 8 , 9 ,'(',')', 0 ,'.','←','C', } local layout = Table.rep( {'button'}, nil, -- You can automatically use #buttons length derived from #caption. { caption=buttons, path = Table.rep( -- Nested call first creates a variation table. {'buttons'}, #buttons, -- Or you can specify the length manually. {[2]=buttons} ) } ) print(Hydra.lines(layout)) > { {"button", caption = 1 , path = {"buttons", 1 }}, {"button", caption = 2 , path = {"buttons", 2 }}, {"button", caption = 3 , path = {"buttons", 3 }}, {"button", caption = "+", path = {"buttons", "+"}}, {"button", caption = "-", path = {"buttons", "-"}}, {"button", caption = 4 , path = {"buttons", 4 }}, {"button", caption = 5 , path = {"buttons", 5 }}, {"button", caption = 6 , path = {"buttons", 6 }}, {"button", caption = "*", path = {"buttons", "*"}}, {"button", caption = "/", path = {"buttons", "/"}}, {"button", caption = 7 , path = {"buttons", 7 }}, {"button", caption = 8 , path = {"buttons", 8 }}, {"button", caption = 9 , path = {"buttons", 9 }}, {"button", caption = "(", path = {"buttons", "("}}, {"button", caption = ")", path = {"buttons", ")"}}, {"button", caption = 0 , path = {"buttons", 0 }}, {"button", caption = ".", path = {"buttons", "."}}, {"button", caption = "←", path = {"buttons", "←"}}, {"button", caption = "C", path = {"buttons", "C"}} }
- remove_nil(tbl)
-
In-place. Shallowly replaces Table.NIL keys and values with nil,
deleting the affected mappings.
Parameters:
- tbl table
Returns:
-
tbl
Conversion
- to_array(tbl[, target=nil])
-
In-place. Converts MixedTable to SparseArray. All keys that are not
NaturalNumbers will be removed.
Parameters:
- tbl table
- target table Copy Mode. This table will be changed and tbl remains unchanged. (default nil)
Returns:
-
SparseArray or DenseArray
A table containing only the numeric keys
of the input array.
- to_string(tbl)
-
Alias of String.to_string.
Parameters:
- tbl table
Returns:
Metamethods
- __concat()
- Addition with + is Table.smerge().
- set_metamethod(tbl, method_name, f)
-
Set a function as metamethod of tbl.
Inherits current metatable or creates a new one.
Will overwrite existing metamethods of the same name.
Parameters:
- tbl table
- method_name string "__index", "__newindex", etc.
- f function or nil A meta handler f(self,...).
Returns:
-
table
This does not automatically inherit any methods of this
Table module.
- get_metamethod(tbl, method_name)
-
Gets the metamethod handler function of tbl.
Parameters:
Returns:
- deep_clear_metatables(tbl)
-
Recursively removes metatables from all subtables but not from other object types.
Parameters:
- tbl table
Returns:
-
table
The input table. Doesn't have a Table module metatable.
Usage:
local test = setmetatable({},{ __index = function() print'first meta' return 1 end, }) -- recursive test.test = test -- different test.foo = setmetatable({},{ __index = function() print'second meta' return 2 end, }) -- metamethods will trigger additional printing local x = test[1] > first meta local x = test.test[1] > first meta local x = test.foo[1] > second meta Table.deep_clear_metatables(test) -- without metatables there is no printing (and also no values in this case). local x = test[1] local x = test.test[1] local x = test.foo[1]
- clear_meta(tbl)
-
Removes any metatable from a table.
Does not recurse into the table.
Parameters:
- tbl table
Returns:
-
table
The input table. Without any metatable whatsoever.
- popmetatable(tbl)
-
Removes and returns the metatable.
Useful for temporarily removing and later reinstating the metatable.
Parameters:
- tbl table
Returns:
Path Methods
- TablePath
- Concept. A DenseArray of values that represent keys of a nested path in another table.
- get(tbl, path[, default=nil])
-
Get the value at location path in tbl.
Parameters:
- tbl table
- path table
- default AnyValue The value that will be returned if the full path points at a nil value or if the path only partially exists in tbl. (default nil)
Returns:
Usage:
local tbl = {a = {b = {c = 42}}} local path = {'a','b','c'} print (Table(tbl):get(path)) > 42
local tbl = {a = {b = {c = 42}}} local path = {'a','b','c','d','e'} print (Table.get(tbl,path,"Don't panic!")) > Don't panic!
- set(tbl, path, value)
-
Set a new value to location path in tbl. Automatically creates subtables
nessecary to fullfill the path.
Parameters:
Returns:
-
value
A reference to the input value given.
- sget(tbl, path, default)
-
Get the value at location path in tbl if it exists, otherwise creates it.
Automatically creates subtables nessecary to fullfill the path.
Parameters:
Returns:
-
AnyValue
A reference to the found value or the default value.
- add(tbl, path, number)
-
Adds a number to an existing value or creates a new value.
Alias:
Table['+='](t,p,n)
Parameters:
- remove(tbl, path)
-
Removes and returns a value from a table.
Does not remove empty sub-tables left behind after removing all keys.
Note: Not to be confused with table.remove which only works on arrays.
Parameters:
Returns:
- TablePatch
- Concept. A DenseArray consisting of a TablePath followed by a TablePatchValue.
- TablePatchValue
-
Concept.
The value part of a TablePatch is not further interpreted unless it is a MixedTable made of a TablePath that contains the mapping{self=true}
. In this case the actual value will be fetched from the table being patched. Mainly used for in-line self refernces during data-stage prototype creation.Fields:
- patch(tbl, patches)
-
Takes an array of patches and applies them to a table.
Parameters:
- tbl table
- patches DenseArray An array of TablePatch.
Returns:
-
table
The input table.
Usage:
local test = {one = 1} Table(test) :patch({{'two',value=2}}) test:patch({ {'deeper','one',value={self=true,copy=true,'one'}}, {'deeper','two',value={self=true,copy=true,'two'}}, }) print(Hydra.line(test)) > {deeper = {one = 1, two = 2}, one = 1, two = 2}
Factories
- normalizer(defaults)
-
Factory. Applies default values to tables.
Parameters:
- defaults table Mappings key→default_value.
Returns:
-
function
TableNormalizerFunction
- TableNormalizerFunction(tbl)
-
In-place. Applies enclosurized defaults.
Parameters:
- tbl table
Returns:
-
Table
The input table.
Usage:
local my_norm = Table.normalizer{name='no name',value=0} print(my_norm{name='testrr'}:to_string()) > {name = "testrr", value = 0}
- remapper(mappings[, allow_tables_as_keys=false])
-
Factory. Moves values from one key to another.
Parameters:
- mappings table Mappings old_key→new_key or old_key→{new_key_1,...,new_key_n}
- allow_tables_as_keys boolean When this is true then new_key of type table will not be interpreted as a DenseArray of new keys but instead used directly as the key. (default false)
Returns:
-
function
TableRemapperFunction
- TableRemapperFunction(tbl)
-
In-place. Applies enclosurized re-mappings.
Parameters:
- tbl table
Returns:
-
Table
The input table.
Usage:
-- with multiple remappings per key local my_remapper1 = Table.remapper {name='surname',value={'cur','act'}} local test_person1 = {name='Adicator',value=42} print(my_remapper1(test_person1):to_string()) > {act = 42, cur = 42, surname = "Adicator"} -- with tables as keys local my_remapper2 = Table.remapper({name='surname',value={'cur','act'}},true) local test_person2 = {name='Bdicator',value=42} print(my_remapper2(test_person2):to_string()) > {[{"cur","act"}] = 42, surname = "Bdicator"}