Extends the Lua 5.2 table library, adding more capabilities and functions.
NOTE: Several functions in this module will only work with arrays, which are tables with sequentially numbered keys. All table functions will work with arrays as well, but array functions will not work with tables.
local table = require("__flib__.table")
array_copy(arr) | Shallow copy an array's values into a new array. |
array_merge(arrays) | Merge all of the given arrays into a single array. |
deep_compare(tbl1, tbl2) | Recursively compare two tables for inner equality. |
deep_copy(tbl) | Recursively copy the contents of a table into a new table. |
deep_merge(tables) | Recursively merge two or more tables. |
find(tbl, value) | Find the value in the table. |
for_each(tbl, callback) | Call the given function for each item in the table, and abort if the function returns truthy. |
for_n_of(tbl, from_k, n, callback[, _next]) | Call the given function on a set number of items in a table, returning the next starting key. |
filter(tbl, filter[, array_insert]) | Create a filtered version of a table based on the results of a filter function. |
invert(tbl) | Invert the given table such that [value] = key , returning a new table. |
map(tbl, mapper) | Create a transformed table using the output of a mapper function. |
partial_sort(arr, from_index, iterations[, comp]) | Partially sort an array. |
reduce(tbl, reducer[, initial_value]) | "Reduce" a table's values into a single output value, using the results of a reducer function. |
retrieve(tbl, key) | Remove and return a value from the table. |
shallow_copy(tbl, use_rawset) | Shallowly copy the contents of a table into a new table. |
shallow_merge(tables) | Shallowly merge two or more tables. |
size(tbl) | Retrieve the size of a table. |
slice(arr[, start=1][, stop=#arr]) | Retrieve a shallow copy of a portion of an array, selected from start to end inclusive. |
splice(arr[, start=1][, stop=#arr]) | Extract a portion of an array, selected from start to end inclusive. |
Shallow copy an array's values into a new array.
This function is optimized specifically for arrays, and should be used in place of table.shallow_copy for arrays.
Parameters:Merge all of the given arrays into a single array.
Parameters:
Recursively compare two tables for inner equality.
Does not compare metatables.
Parameters: Returns:Recursively copy the contents of a table into a new table.
Does not create new copies of Factorio objects.
Parameters:Recursively merge two or more tables.
Values from earlier tables are overwritten by values from later tables, unless both values are tables, in which case they are recursively merged.
Non-merged tables are deep-copied, so the result is brand-new.
Parameters:local tbl = {foo = "bar"}
log(tbl.foo) -- logs "bar"
log (tbl.bar) -- errors (key is nil)
tbl = table.merge{tbl, {foo = "baz", set = 3}}
log(tbl.foo) -- logs "baz"
log(tbl.bar) -- logs "3"
Find the value in the table.
Parameters:
eq
metamethod set, otherwise will error.
nil
if it was not found.
local tbl = {"foo", "bar"}
local key_of_foo = table.find(tbl, "foo") -- 1
local key_of_baz = table.find(tbl, "baz") -- nil
Call the given function for each item in the table, and abort if the function returns truthy.
Calls callback(value, key)
for each item in the table, and immediately ceases iteration if the callback
returns truthy.
local tbl = {1, 2, 3, 4, 5}
-- run a function for each item (identical to a standard FOR loop)
table.for_each(tbl, function(v) game.print(v) end)
-- determine if any value in the table passes the test
local value_is_even = table.for_each(tbl, function(v) return v % 2 == 0 end)
-- determine if ALL values in the table pass the test (invert the test result and function return)
local all_values_less_than_six = not table.for_each(tbl, function(v) return not (v < 6) end)
Call the given function on a set number of items in a table, returning the next starting key.
Calls callback(value, key)
over n
items from tbl
, starting after from_k
.
The first return value of each invocation of callback
will be collected and returned in a table keyed by the
current item's key.
The second return value of callback
is a flag requesting deletion of the current item.
The third return value of callback
is a flag requesting that the iteration be immediately aborted. Use this flag to
early return on some condition in callback
. When aborted, for_n_of
will return the previous key as from_k
, so
the next call to for_n_of
will restart on the key that was aborted (unless it was also deleted).
DO NOT delete entires from tbl
from within callback
, this will break the iteration. Use the deletion flag
instead.
nil
to start at the beginning of tbl
. If the key does
not exist in tbl
, it will be treated as nil
, unless a custom _next
function is used.
value
and key
as parameters.
next()
function. If not provided, the default next()
will be used.
(optional)
nil
.
Pass this as from_k
in the next call to for_n_of
for tbl
.
callback
.
local extremely_large_table = {
[1000] = 1,
[999] = 2,
[998] = 3,
...,
[2] = 999,
[1] = 1000,
}
event.on_tick(function()
global.from_k = table.for_n_of(extremely_large_table, global.from_k, 10, function(v) game.print(v) end)
end)
Create a filtered version of a table based on the results of a filter function.
Calls filter(value, key)
on each element in the table, returning a new table with only pairs for which
filter
returned a truthy value.
value
, key
, and tbl
as parameters.
local tbl = {1, 2, 3, 4, 5, 6}
local just_evens = table.filter(tbl, function(v) return v % 2 == 0 end) -- {[2] = 2, [4] = 4, [6] = 6}
local just_evens_arr = table.filter(tbl, function(v) return v % 2 == 0 end, true) -- {2, 4, 6}
Invert the given table such that [value] = key
, returning a new table.
Non-unique values are overwritten based on the ordering from pairs()
.
local tbl = {"foo", "bar", "baz", set = "baz"}
local inverted = table.invert(tbl) -- {foo = 1, bar = 2, baz = "set"}
Create a transformed table using the output of a mapper function.
Calls mapper(value, key)
on each element in the table, using the return as the new value for the key.
local tbl = {1, 2, 3, 4, 5}
local tbl_times_ten = table.map(tbl, function(v) return v * 10 end) -- {10, 20, 30, 40, 50}
Partially sort an array.
This function utilizes insertion sort, which is extremely
inefficient with large data sets. However, you can spread the sorting over multiple ticks, reducing the performance
impact. Only use this function if table.sort
is too slow.
nil
or a number less than 2
to begin
at the start of the array.
comp
function (if any) and the size of the array.
a < b
.
(optional)
"Reduce" a table's values into a single output value, using the results of a reducer function.
Calls reducer(accumulator, value, key)
on each element in the table, returning a single accumulated output value.
accumulator
value and skipped as key
. Calling reduce()
on an empty
table without an initial_value
will cause a crash.
(optional)
local tbl = {10, 20, 30, 40, 50}
local sum = table.reduce(tbl, function(acc, v) return acc + v end)
local sum_minus_ten = table.reduce(tbl, function(acc, v) return acc + v end, -10)
Remove and return a value from the table.
Parameters:
Shallowly copy the contents of a table into a new table.
The parent table will have a new table reference, but any subtables within it will still have the same table reference.
Does not copy metatables.
Parameters: Returns:Shallowly merge two or more tables.
Unlike table.deep_merge, this will only combine the top level of the tables.
Parameters:Retrieve the size of a table.
Uses Factorio's built-in table_size
function.
Retrieve a shallow copy of a portion of an array, selected from start
to end
inclusive.
The original array will not be modified.
Parameters:n
items from the end of the array.
(default: #arr)
local arr = {10, 20, 30, 40, 50, 60, 70, 80, 90}
local sliced = table.slice(arr, 3, 7) -- {30, 40, 50, 60, 70}
log(serpent.line(arr)) -- {10, 20, 30, 40, 50, 60, 70, 80, 90} (unchanged)
Extract a portion of an array, selected from start
to end
inclusive.
The original array will be modified.
Parameters:n
items from the end of the array.
(default: #arr)
local arr = {10, 20, 30, 40, 50, 60, 70, 80, 90}
local spliced = table.splice(arr, 3, 7) -- {30, 40, 50, 60, 70}
log(serpent.line(arr)) -- {10, 20, 80, 90} (values were removed)