Page 2 of 2

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

Posted: Wed Dec 14, 2016 12:59 am
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

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

Posted: Wed Dec 14, 2016 1:46 am
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.

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

Posted: Wed Dec 14, 2016 2:02 am
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

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

Posted: Wed Dec 14, 2016 3:50 am
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!

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

Posted: Wed Dec 14, 2016 6:20 am
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``````

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

Posted: Wed Dec 14, 2016 6:38 am
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!