Table2 | module for more flexibility on tables

Yable was renamed to Table(version) for it’s new purpose.
This is a module as a way to improve myself and showcase my abilities for the work I do. I’ll be glad to add any of your suggestions!

The difference is that I plan to use it as an add-on to table methods, not an alternative

hey :hugs:, so im making public this module i had made for development of my games some time ago. it builds onto the existing roblox table functions and adds missing methods that constantly need you to be making functions everywhere.

there’s some tools than can be useful in real world scenarios such as if you have a list of items and want to randomize their order, calculate their sum, combine them pairwise, find the items unique to each list, excluding duplicates and assisting your datastore with easily removing duplicates etc

for example, i used it on a crate spin system that went crazy, first rotating the table then shuffling after 2 iterations, it looked great and its a more event based and simple approach.

latest version's changelog

you can now use table as a core roblox library!

by declaring the module as table anywhere!
for example

-- Declare table2 as table
local table = require(path.to.table2)

local t1 = {"foo", 3}

-- Fully works with original table library
table.insert(t1, 9) -- > Inserts 9 to t1, as normal
table.shuffle(t1) ---> Shuffles t1, ex., becomes {9, 3, "foo"}, with 9 now.

it just builds onto the existing elements and makes it easier without needing to lose your muscle memory, which is what i recommend. however, if you don’t like it for any reason, theres 2 versions. addon and separate, downloadable separately (updated at the same time)

for example:

-- Separate version
local yable = require(path.to.table_s)

local t1 = {"foo", 3}
-- Now, doing this is not possible
yable.insert(t1, 9) -- > Doesn't exist
yable.shuffle(t1) -- > Works

-- Add-on version
local table = require(path.to.table_a)
-- Any built-in is possible
table.insert(t1, 9) -- > Works
table.shuffle(t1) -- > Works

table.math added!

simplify your statistics for your projects, benchmarks, group mathematical operations, average of judges score, inventory sizes, lowest and highest sets in data, random based economies, anything.

the functions are accesible both as a sub method under table

-- Declaring table first 
local table = require(path.to.table)

-- Then easily access by using .math after table
local myNumbers = {1, 2, 3, 4, 5}
local myResult = table.math.sum(myNumbers)

print(myResult) ---> 15

or optionally, you can declare it as an alternate version

-- Declaring table.math as tmath
local tmath = require(path.to.table).math

-- Works separately
local myNumbers = {1, 2, 3, 4, 5}
local myResult = tmath.sum(myNumbers)

print(myResult) ---> 15

shouldnt interfere much if you only want the math methods

and for table.math / tmath, the functions are

math.sum
math.sub
math.product
math.mean
math.count
math.median
math.min
math.max ( also accesible as table.maxn for compatibility and simplicity )
math.variance
math.standardDeviation
math.mode
math.range
math.normalize
math.percentile
math.correlation
math.accumulate ( accumulate is how math.sum, sub and product work with a accumulator function, such as: )

local factors = {2, 3, 4}
local product = tmath.accumulate(factors, function(acc, val) return acc * val end, 1) 
print(product) -- Output: 24  

added for table

  1. table.vfind (suggested by @IceMinisterq): finds a entry in a table from a value and not thru index
local t1 = {
	a1 = "hey",
	b2 = 1,
	c3 = 89
}

local find = table.find(t1, "hey") -- > nil
local vfind = table.vfind(t1, "hey") -- > a1
  1. table.fill: fills an arrays values with another, optionally starting at a index and ending at another optional index
local myArray = {}
table.fill(myArray, 1, 1, 20) 
print("Initialized empty array:", myArray) 

-- resetting portions of a table:
local scores = {15, 8, 22, 10}
table.fill(scores, 0, 2, 4) 
print("Scores after reset:", scores) 

-- luck based mechanics:
local myPlayers = {"roblox", "Jake", "builderman", "QLP", "Guest"}
table.shuffle(myPlayers)

local luckyPlrs = table.fill(myPlayers, nil, 2, 5) 
print("Lucky player:", luckyPlrs) 

-- It can also be used for clearing tables, but table.clear already does that job.

random way to use table.fill
gradient effect

local numSteps = 50
local gradient = table.fill({}, {r = 0, g = 0, b = 1}, 1, numSteps) -- start with blue

for i = 2, numSteps do
	gradient[i] = {
		r = gradient[i - 1].r + 1/numSteps,  -- increment red
		g = gradient[i - 1].g,
		b = gradient[i - 1].b - 1/numSteps  -- decrement blue
	}
end

  1. keys method that returns only the keys
local playerStats = {health = 100, mana = 50, strength = 15}
local statNames = table.keys(playerStats)

for _, statName in ipairs(statNames) do
	print(statName, playerStats[statName]) 
end 
-- Output: health 100, mana 50, strength 15
  1. values method that only returns values
    example usage with both values and keys method
local playerData = {
	["Alice"] = {score = 1800, coins = 52, level = 15},
	["Bob"] = {score = 1250, coins = 38, level = 12},
	["Charlie"] = {score = 2500, coins = 80, level = 20}
}

-- all player names
local playerNames = table.keys(playerData)
print("Player Names:", playerNames) 
-- Output: Player Names: {Alice, Bob, Charlie}

-- all score values
local scores = table.values(playerData)
print("Scores:", scores) 
-- Output: Scores: {{score = 1800, coins = 52, level = 15}, ... }

-- get the highest score:
local highestScore = 0
for _, playerInfo in ipairs(scores) do
	if playerInfo.score > highestScore then
		highestScore = playerInfo.score
	end
end
print("Highest Score:", highestScore) -- Output: Highest Score: 2500
  1. renaming/removing of superseded functions
functions
function reverse(t : {any}) : void

Reverses the order of elements in a table.

function vfind(haystack: {any}, needle: any, init: number | nil): any

Searches for a value within a table and returns the key where the match is found.

function map(t: {any}, f): {any}

Creates a new table by applying a transformation function to each element of the original table.

function filter(t: {any}, f): {any}

Creates a new table containing only the elements from the original table that pass a test function.

function fill(t: {any}, value: any, start: number | nil, finish: number | nil): {any} 

Fills a table (or part of it) with a specified value.

function accumulate(t: {any}, f, initial: number | nil): any

Reduces a table to a single value by cumulatively applying a function.

function slice(t, start, finish): {any}

Extracts a portion of a table into a new table.

function shuffle(t: {any}): void

Randomizes the order of elements within a table.

function isempty(t: {any}): boolean

Checks if a table is empty (has no elements).

function deepclone(t: {any}): {any}

Creates a deep copy of a table, including nested tables.

function flatten(t: {any}) : {any}

Flattens a nested table into a single-level array.

function keys(t: {any}) : {any}

Collects all the keys of a table into a new table.

function values(t: {any}) : {any}

Collects all the values of a table into a new table.

function merge(t1: {any}, t2: {any}) : {any} 

Combines two tables into a new table.

function mergekeep(t1: {any}, t2: {any}) : {any}

Combines two tables and only adds unique keys from t2 into t1.

function mergeoverwrite(t1: {any}, t2: {any}) : {any}

Combines two tables, overwriting values in t1 with any matching keys in t2.

function intersection(t1: {any}, t2: {any}): {any}

Creates a new table containing the elements present in both input tables.

function difference(t1: {any}, t2: {any}): {any}

Creates a new table containing the elements in the first table that are not present in the second.

function union(t1: {any}, t2: {any}): {any}

Creates a new table containing all elements from both input tables, removing duplicates.

function group_by(t: {any}, keyFunc): {any}

Groups elements in a table based on the result of a key-generating function.

function flatten_deep(t: {any}): {any}

Flattens a nested table (with arbitrary depth) into a single-level array.

function rotate(t: {any}, n: number): {any}

Rotates the elements of a table by a specified number of positions.

function split(t: {any}, predicate) : trueValues, falseValues

Splits a table into two new tables based on whether elements pass a test function.

function contains(t : {any}, value : any) : boolean 

Checks if a table contains a specific value.

function zip(t1: {any}, t2: {any}): {any}

Pairs corresponding elements from two tables into two-element tables.

function chunk(t: {any}, size: number): {{any}}

Splits a table into smaller tables (chunks) of a specified size.

function purgeshared(t1: {any}, t2: {any}) : {any}

Creates a table containing the unique elements from both input tables (elements not present in both).

let me know if i should anything to the module, ill try to update it.

do you like it?
  • yes
  • meh
  • noo

0 voters

should i add better documentation?
  • yes
  • it’s fine
  • noo

0 voters

get the versions here

addon version that builds over table methods. allows you to declare the module as “table”. (explained earlier)

separate version that removes core table functions, can not be declared as “table”. (also explained earlier)

9 Likes

Now make a find method that supports Lua tables
(this)

local x = {
    ["a"] = 1,
    ["b"] = 2,
    ["c"] = 3
}

There’s table.find already which already assist you on that, however if you detail more on a specific method of finding, I’ll gladly put it in.

For my previous project, I was working on permutation and a system to get all possible combinations (without a table overflow) I’ll soon implement so I can add it with yours.

I’m fairly sure he asked you to create a find method that supports dictionaries, since the default table.find only works with numeric arrays.

1 Like

Oh, I see. I’ll get to add it. Currently, I’m working on a better alternative to my module which will basically just build onto the existing methods of table without a different name and just 2 lines in any script to expand roblox’s library methods.

I’ll have it in the queue of things to add.

rrarara

Also, I’m not sure if you’re aware, but Sift exists.

Oh wow, didn’t know such thing existed. I’ll look into it

I have looked into it, it’s good, probably a better alternative to what I’m doing. I see it creates modules for already existing functions in roblox though which isn’t that much optimized but I guess it’s not even noticeable.

1 Like

Version 2 released

  • table.math added
  • more table methods (keys, values, fill and more)
  • Yable is now Table
  • Many more details in the changelog
1 Like

Also maybe instead of defining at the beginning

local Table = { 
   insert = table.insert,
   ...
}

You can use

setmetatable(Table, {
	__index = table
})

Wow! I didn’t think about that. I’m reworking this module for better naming and mainly for my personal use, but if I ever update it ill make sure to use the metatable. It also makes more sense because you now have the text that tells you how the function works.

1 Like