## Hey, so here's a couple functions!

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Nicholas Scott
Prole
Posts: 49
Joined: Sun Jun 07, 2015 9:12 am

### Re: Hey, so here's a couple functions!

Haha I love what this has become , I'm gonna edit the post and add the functions Positive07 did with credit ofc but not remove the originals, just in case someone wants them, or when they look at the post they don't get confuzzled haha, Great job by the way Positive, I didn't really focus on optimization or usefulness, I just threw the hard math down and such but you did a great job Love the work <3 Oh and if anyone finds anything cool with these, please post here, I haven't found anything useful with it yet except maybe some cool effect, not really sure, but yeah

Sir_Silver
Party member
Posts: 286
Joined: Mon Aug 22, 2016 2:25 pm
Contact:

### Re: Hey, so here's a couple functions!

Here are some functions I made which you may find some use for.

Code: Select all

function table.clone(tab, tab2)
local clone = tab2 or {}

for k, v in pairs(tab) do
if type(v) == "table" then
clone[k] = {}
table.clone(v, clone[k])
else
clone[k] = v
end
end

return clone
end
This will allow you to take all of the elements from one table and create a new table with all of the same elements. Using recursion, it's able to delve into any of the tables inside of the table you want to copy, and so on, to continue the copying process.

Code: Select all

function PrintTable(tab, indents, printed)
local spaces = ""
indents = indents or 0
printed = printed or {}

for i = 1, indents do
spaces = spaces .. "        "
end

printed[tab] = true

for k, v in pairs(tab) do
if type(v) == "table" and not printed[v] then
print(spaces .. k .. ":")
PrintTable(v, indents + 1, printed)
else
print(spaces .. k .. ":", v)
end
end
end
If you're familiar with gmod lua, you may already be acquanted with the PrintTable function, this is my take on it, which for what little testing I've done, believe is actually better than the way it works in gmod - because if __index points to the table passed to the function, it won't print everything inside of it again.

Basically it turns this:

Code: Select all

local tab = {
{
1,
2,
"sky",
red = {
true,
function() end
},
"blue"
},
"two",
true
}

tab.__index = tab

PrintTable(tab)
Into this print:

Code: Select all

1:
1:	1
2:	2
3:	sky
4:	blue
red:
1:	true
2:	function: 0x1473140
2:	two
3:	true
__index:	table: 0x14725f0	
Pretty neat, huh?

EDIT: I changed the table.clone function, so this time it creates a new table instead of using table references.
Last edited by Sir_Silver on Sat Dec 24, 2016 1:14 pm, edited 5 times in total.

Nicholas Scott
Prole
Posts: 49
Joined: Sun Jun 07, 2015 9:12 am

### Re: Hey, so here's a couple functions!

Sir_Silver wrote:Here are some functions I made which you may find some use for.
...
Pretty neat, huh?
Yeah it is you show off! Jk, great stuff, I actually started my "programming knowledge" on GLua and was sad when I found out the PrintTable function wasn't native to Lua haha, good stuff bro

Sir_Silver
Party member
Posts: 286
Joined: Mon Aug 22, 2016 2:25 pm
Contact:

### Re: Hey, so here's a couple functions!

Nicholas Scott wrote:
Sir_Silver wrote:Here are some functions I made which you may find some use for.
...
Pretty neat, huh?
Yeah it is you show off! Jk, great stuff, I actually started my "programming knowledge" on GLua and was sad when I found out the PrintTable function wasn't native to Lua haha, good stuff bro
Hey, that's pretty awesome! Didn't figure there were any gmod programmers here. Gmod is where I started learning how to program first too!

ivan
Party member
Posts: 1614
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

### Re: Hey, so here's a couple functions!

Not bad, Sir_Silver, it seems like you're headed in the right direction with the code.
I'm not 100% but this looks like a bug:

Code: Select all

        clone[k] = v
if type(v) == "table" then
table.clone(v, true)
end
Without creating a new table "{}", the code would only make a reference so it's not a "deep copy".
Also note that cycles will crash the code above, for example "a = {}; a.b = a".
Note that:

Code: Select all

   for i = 1, indents do
spaces = spaces .. "        "
end
Can become:

Code: Select all

spaces = string.rep("   ", indents)
Also, the following part assumes k is a string or a number:

Code: Select all

spaces .. k .. ":"
It's safer to write:

Code: Select all

spaces .. tostring(k) .. ":"
A while ago I wrote a similar table "utilities" file, here it is in a nutshell:

Code: Select all

local _cache = {}

--- Checks if a table is empty
-- @param t Table
-- @return True if empty or false otherwise
function table.empty(t)
return next(t) == nil
end

--- Removes all values
-- @param t Table
function table.clear(t)
for i in pairs(t) do
t[i] = nil
end
end

--- Counts the number of elements
-- @param t Table
-- @return Number of non-nil values
function table.count(t)
local n = 0
for _ in pairs(t) do
n = n + 1
end
return n
end

--- Counts the number of unique elements
-- @param t Table
-- @return Number of unique and non-nil values
function table.ucount(t)
local n = 0
local d = 0
for _, v in pairs(t) do
if _cache[v] then
d = d + 1
end
n = n + 1
_cache[v] = true
end
-- clear the cache
table.clear(_cache)
return n - d, n
end

--- Counts the number of occurrences of a given value
-- @param t Table
-- @param v Value
-- @return Number of occurrences and non-nil values
function table.vcount(t, s)
assert(s ~= nil, "second argument cannot be nil")
local n = 0
local d = 0
for _, v in pairs(t) do
if v == s then
d = d + 1
end
n = n + 1
end
return d, n
end

--- Reverses the elements in a list
-- @param t Table
-- @param r Destination table (optional)
-- @return Reversed table
function table.reverse(t, r)
r = r or t
local n = #t
if t == r then
-- reverse in place
for i = 1, n/2 do
local i2 = n - i + 1
r[i], r[i2] = r[i2], r[i]
end
else
-- reverse copy
for i = 1, n do
r[n - i + 1] = t[i]
end
end
return r
end

--- Finds the first occurrence in a list
-- @param t Table
-- @param s Search value
-- @param o Starting index (optional)
-- @return Numeric index or nil
function table.find(t, s, o)
o = o or 1
assert(s ~= nil, "second argument cannot be nil")
for i = o, #t do
if t[i] == s then
return i
end
end
end

--- Finds the last occurrence in a list
-- @param t Table
-- @param s Search value
-- @param o Starting index (optional)
-- @return Numeric index or nil
function table.rfind(t, s, o)
o = o or #t
assert(s ~= nil, "second argument cannot be nil")
-- iterate in reverse
for i = o, 1, -1 do
if t[i] == s then
return i
end
end
end

--- Recursive deep copy (internal)
--- "cache" must be empty prior to calling this function
-- @param s Source table
-- @param d Destination table
local function dcopy(s, d)
-- copy elements from the source table
for k, v in pairs(s) do
if type(v) == "table" then
if _cache[v] then
-- reference cycle
d[k] = _cache[v]
else
-- recursive copy
local d2 = d[k]
if d2 == nil then
d2 = {}
d[k] = d2
end
_cache[v] = d2
dcopy(v, d2)
end
else
d[k] = v
end
end
end

--- Copies the contents from one table to another
--- Overwrites existing elements in the destination table
--- Preserves table cycles
-- @param s Source table
-- @param d Destination table (optional)
-- @return Resulting table
function table.copy(s, d)
d = d or {}
assert(s ~= d, "source and destination tables must be different")
-- clear the cache
table.clear(_cache)
-- deep copy
dcopy(s, d)
return d
end
Last edited by ivan on Wed Dec 14, 2016 7:09 am, edited 1 time in total.

Sir_Silver
Party member
Posts: 286
Joined: Mon Aug 22, 2016 2:25 pm
Contact:

### Re: Hey, so here's a couple functions!

Thanks for the feedback on that, Ivan, I didn't thoroughly test that function enough, I'll be sure to fix it up when I get the chance!

### Who is online

Users browsing this forum: pgimeno and 12 guests