Skip to content

Instantly share code, notes, and snippets.

@EtiTheSpirit
Last active July 14, 2021 21:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EtiTheSpirit/393e9a4404faafb9f09016059ea77e23 to your computer and use it in GitHub Desktop.
Save EtiTheSpirit/393e9a4404faafb9f09016059ea77e23 to your computer and use it in GitHub Desktop.
local RNG = Random.new()
local Table = {}
-- Returns true if the table contains the specified value.
Table.contains = function (tbl, value)
return Table.indexOf(tbl, value) ~= nil -- This is kind of cheatsy but it promises the best performance.
end
-- A combo of table.find and table.keyOf -- This first attempts to find the ordinal index of your value, then attempts to find the lookup key if it can't find an ordinal index.
Table.indexOf = function (tbl, value)
local fromFind = table.find(tbl, value)
if fromFind then return fromFind end
return Table.keyOf(tbl, value)
end
-- Returns the key of the specified value, or nil if it could not be found. Unlike IndexOf, this searches every key in the table, not just ordinal indices (arrays)
-- This is inherently slower due to how lookups work, so if your table is structured like an array, use table.find
Table.keyOf = function (tbl, value)
for index, obj in pairs(tbl) do
if obj == value then
return index
end
end
return nil
end
-- ONLY SUPPORTS ORDINAL TABLES (ARRAYS). Skips *n* objects in the table, and returns a new table that contains indices (n + 1) to (end of table)
Table.skip = function (tbl, n)
return table.move(tbl, n+1, #tbl, 1, table.create(#tbl-n))
end
-- ONLY SUPPORTS ORDINAL TABLES (ARRAYS). Takes *n* objects from a table and returns a new table only containing those objects.
Table.take = function (tbl, n)
return table.move(tbl, 1, n, 1, table.create(n))
end
-- ONLY SUPPORTS ORDINAL TABLES (ARRAYS). Takes the range of entries in this table in the range [start, finish] and returns that range as a table.
Table.range = function (tbl, start, finish)
return table.move(tbl, start, finish, 1, table.create(finish - start + 1))
end
-- ONLY SUPPORTS ORDINAL TABLES (ARRAYS). An alias that calls table.skip(skip), and then takes [take] entries from the resulting table.
Table.skipAndTake = function (tbl, skip, take)
return table.move(tbl, skip + 1, skip + take, 1, table.create(take))
end
-- ONLY SUPPORTS ORDINAL TABLES (ARRAYS). Selects a random object out of tbl
Table.random = function (tbl)
return tbl[RNG:NextInteger(1, #tbl)]
end
-- ONLY SUPPORTS ORDINAL TABLES (ARRAYS). Merges all the given tables together. Very fast compared to standard table.join
Table.joinArray = function (...)
local tbls = {...}
local size = 0
local at = 1
for i = 1, #tbls do
size += #tbls[i]
end
local newTbl = table.create(size)
for i = 1, #tbls do
local tbl = tbls[i]
table.move(tbl, 1, #tbl, at, newTbl)
at += #tbl
end
return newTbl
end
-- A slower variant of table.joinArray which supports dictionaries.
Table.join = function (...)
local tbls = {...}
local newTbl = {}
for i = 1, #tbls do
for index, value in pairs(tbls[i]) do
newTbl[index] = value
end
end
return newTbl
end
-- ONLY SUPPORTS ORDINAL TABLES (ARRAYS). Removes the specified object from this array.
Table.removeObject = function (tbl, obj)
local index = Table.indexOf(tbl, obj)
if index then
table.remove(tbl, index)
end
end
-- ONLY SUPPORTS ORDINAL TABLES (ARRAYS). Iterates through the given table and returns all instances from which the given predicate function returns true as an array.
Table.where = function (tbl, predicate)
local result = table.create(#tbl)
for i = 1, #tbl do
local object = tbl[i]
if (predicate(object)) then
table.insert(result, object)
end
end
return result
end
-- ONLY SUPPORTS ORDINAL TABLES (ARRAYS). Iterates through the given table and returns the first occurrence from the table from which the given predicate function returns true. Returns default otherwise.
Table.first = function (tbl, predicate, default)
for i = 1, #tbl do
local object = tbl[i]
if (predicate(object)) then
return object
end
end
return default
end
-- ONLY SUPPORTS ORDINAL TABLES (ARRAYS). Iterates through the given table, and counts the amount of elements that meet the given requirement as defined by the predicate.
Table.count = function (tbl, predicate)
local count = 0
for i = 1, #tbl do
local object = tbl[i]
if (predicate(object)) then
count += 1
end
end
return count
end
-- ONLY SUPPORTS ORDINAL TABLES (ARRAYS). Iterates through the given table, and runs the transformer function on all elements, populating a new table with the given data rather than modifying the original table.
-- If the transformer returns nil, it will be removed from the table.
Table.transform = function (tbl, transform)
local newTbl = table.create(#tbl)
local actualIndex = 1
for i = 1, #tbl do
local element = tbl[i]
local newElement = transform(element)
if newElement == nil then continue end
newTbl[actualIndex] = newElement
actualIndex += 1
end
return newTbl
end
-- ONLY SUPPORTS ORDINAL TABLES (ARRAYS). Removes all elements from the given table who cause predicate to return TRUE.
Table.removeWhere = function (tbl, predicate)
for i = #tbl, 1, -1 do -- Reverse so removal isn't messing things up
local element = tbl[i]
if predicate(element) == false then
table.remove(tbl, i)
end
end
return tbl
end
-- ONLY SUPPORTS ORDINAL TABLES (ARRAYS). Returns a shallow copy of this table, which is a copy of all first level entities by reference.
Table.shallowCopyArray = function (tbl)
local newTbl = table.create(#tbl)
for i = 1, #tbl do
newTbl[i] = tbl[i]
end
return newTbl
end
-- Supports dictionaries. Returns a shallow copy of this table, which is a copy of all first level entities by reference.
-- Prefer shallowCopyArray for ordered lists with no gaps and numeric indices, as it will be much faster
Table.shallowCopy = function (tbl)
local newTbl = {}
for index, value in pairs(tbl) do
newTbl[index] = value
end
return newTbl
end
-- ONLY SUPPORTS ORDINAL TABLES (ARRAYS). Returns a new table containing the identical elements to the given table, but in reverse order.
Table.reverse = function (tbl)
-- TODO: Can I use table.move here?
local newTbl = table.create(#tbl)
for i = 1, #tbl do
local obj = tbl[i]
newTbl[(#tbl - i) + 1] = obj
end
return newTbl
end
return setmetatable(Table, {__index = table})
-- Return the custom Table library, and use the default Roblox "table" variable as the fallback, which allows overriding table
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment