But it is kind of messy so I made it a little bit better (It also has typechecking)
-- Filters a table based on a predicate function.
local function filter<K, V>(table : {[K]: V}, callback : (K, V) -> boolean) : {[K]: V}
local result = {}
for i, v in table do
if callback(i, v) then
result[i] = v
end
end
return result
end
And also the compare function
local function compare(x, ...)
return table.find({...}, x) ~= nil
end
It just simplifies your if statements so instead of doing this
if foo == bar and foo == baz and foo == qux then
-- ...
end
You can do this
if compare(foo, bar, baz, qux) then
-- ...
end
I know this isn’t a lot but I thought it would be helpful for some people so there you go
Creating an array just for comparisons then doing a table.find call doesn’t seem quite fast though, in alot of cases doing it the traditional way would be miles faster… And for filter, just don’t put in incorrect elements in the first place. But if your code doesn’t need to be fast and maybe you like js, this is a pretty solid post.
Heres a function I’d like to add which I use quite alot:
local function jumpTable<T..., R...>(cases: {[any | "_"]: (T...) -> (R...)}) -> (caseItem: any, T...) -> (R...)
return function(case, ...)
local handler = cases[case]
if handler then return handler(...) end
local default = cases._
if not default then return end
return default(...) -- Default case
end
end
It is essentially a switch statement; you can do this:
local jump = jumpTable {
Monday = function() print("It Is Monday") end,
Tuesday = function() print("It Is Tuesday") end,
_ = function() warn("Unknown day") end
}
jump("Monday")
jump("Saturday") -- Unknown day
It is quite nice for places where you have alot of possible values for something, makes it faster but also reduces overall nesting
Or if you wanna get really fancy you can also use metatables to do this:
local t = setmetatable({
Monday = function ()
print("I hate mondays")
end,
_default = function ()
print("I hate unknown days")
end,
},
{
__index = function (t, k)
return rawget(t, k) or rawget(t, "_default")
end
}
)
t["Monday"]() --> I hate mondays
t["Tuesday"]() --> I hate unknown days
Cryo is a library that provides a set of utilities for working with tables, treating them as dictionaries and lists (key-value or dictionary-like like tables and index-value or list-like tables)
-- with cryo
local Cryo = require(script.Cryo)
local players = {
{ name = "Alice", score = 100 },
{ name = "Bob", score = 50 },
{ name = "Charlie", score = 150 }
}
local highScorers = Cryo.List.map(
Cryo.List.filter(players, function(player) return player.score > 75 end),
function(player) return player.name end
)
print(highScorers)
-- Yo, this is so reaable!
-- no cryo:
local players = {
{ name = "Alice", score = 100 },
{ name = "Bob", score = 50 },
{ name = "Charlie", score = 150 }
}
local highScorers = {}
for _, player in ipairs(players) do
if player.score > 75 then
table.insert(highScorers, player.name)
end
end
print(highScorers)
--Oh no! So ugly!!
btw Im also recomend use Symbol.
because Symbol(“F”) == Symbol(“F”) is false, you can do something like pseudo private
local Symbol = require(script.Symbol)
local function tryToAddPrivate(o)
local symbolKey = Symbol.for_('Hi')
o[symbolKey] = 42
end
local obj = { prop = 'hello' }
tryToAddPrivate(obj)
print( obj[Symbol.for_('Hi')] ) -- 42
print( obj.Hi ) -- nil
There is a difference. And, I think, creating a “new symbol” sounds much better, rather than “I created my own user data”.
It pisses me off when people say the obvious things like no one understands.
what could the difference possibly be, also, you dont have to say “i created my own user data” you can just call it a symbol? what sounds so much worse for me is having to require a module every single time i have to create a symbol-like data structure, like okay if you dont wanna fw userdata then just do local symbolKey = {} it does the same thing
I may be damn stupid, but what is the purpose of it?
table.sort does the exact same thing to me?
If you want to remove something entirely, you can just do table.remove() which will be 99999 times more optimized, and you will be able to come back to the code and say, “Oh yeah, I understand what it does.”
without abstracting already quadrillion times abstracted lua tables
not to mention that anonimous functions is a hell for gc to handle
What’s the point of that?
It’s not Java or C#; it’s Luau.
And on Luau, you should program well in Luau code!
This kind of “abstraction” is doing the opposite of helping and is bloatwaring the code to an unreadable state that is also making the code laggy.
Also, you should reference keys directly because indexing them is expensive ( --!optimize 2 doesn’t work on user-defined tables).