This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Joe3000's profile picture

How To Correctly Use Table.remove?

Started by Joe3000, 25 July 2013 - 01:43 AM
Joe3000 #1
Posted 25 July 2013 - 03:43 AM
So I was making a program that used table.remove and I noticed that it never actually removed anything, so I made a test program to try different ways to use table.remove and none of them worked!

local tbl = {string2 = "hello"; bla = 2;}
table.remove(tbl, 1)
--[[table.remove(tbl, 2)
table.remove(tbl[1])
table.remove(tbl, [1])
none of these worked]]
print(tbl.string2)
print(tbl.bla)
Grim Reaper #2
Posted 25 July 2013 - 03:48 AM
http://www.lua.org/pil/19.2.html

table.remove takes two arguments: source table and the index of the element you're removing.

You need to use it with the EXACT index of the element you're removing:

table.remove (tbl, string2)
Joe3000 #3
Posted 25 July 2013 - 03:51 AM
I tried that one as well, I forgot to mention that in the comment, it doesn't work either
Sharidan #4
Posted 25 July 2013 - 03:54 AM
Well, from what I have learned, tables that you build up manually, usually wont be correctly indexed and that's why table.remove() doesnt appear to work properly.
Remember that tables can pretty much hold any form you want, but they have to be ordered like arrays in order to work with the different table manipulation methods.

A table set up like in your example, is ordered like a dictionary:


local tbl = { string2 = "hello", bla = "2" }
print(tbl["string"])
print(tbl["bla"])

The above sample (yours) will then print "hello" on one line and "2" on another.


local tbl = { [1] = "hello", [2] = "2" }
-- or:
local tbl = {}
table.insert(tbl, "hello")
table.insert(tbl, "2")

This second example orders the table in array form and will then allow you to use table.remove() to remove something from it. Choose this second format when you want to manipulate entries by adding more (using: table.insert()) or remove some (using: table.remove())

Syntax:
table.insert( <tableName>, [beforeIndex], <value> )

table.remove( <tableName>, [index] )

<required>
[optional]
Joe3000 #5
Posted 25 July 2013 - 04:07 AM
Alright, that makes sense, but what if I insert a function into a table using table.insert, would that function be just like the second format?([whatever] = funtion()?) or would it be formatted some other way, because essentially that is what i'm doing in my program, inserting a function and if later that function returns true, remove it
Grim Reaper #6
Posted 25 July 2013 - 04:09 AM
It looks like that table.remove doesn't remove elements with non-numerical indexes since it tries to shift indexes after the removal. You'll just have to do:


tbl.string2 = nil

to remove elements with non-numerical indexes.


For what you're doing, I would suggest manipulating the indexes manually instead of using some function as a wrapper, like table.remove.
Sharidan #7
Posted 25 July 2013 - 04:47 AM
If you are using table.insert() and table.remove() to alter the list contents of a table, it doesnt matter what the element / value is, so yes: you can add functions and remove them again.

For example:


function a()
  print("a")
end
function b()
  print("this is from b")
end
local tbl = {}
table.insert(tbl, "hello") -- string value
table.insert(tbl, 42) -- number - the answer to life, the universe and all that
table.insert(tbl, a ) -- the function a
table.insert(tbl, b ) -- the function b
table.insert(tbl, "last one!") -- string again

You wouldnt be able to just print() this table, but you can freely add any value you want to the table and then use type() to check what's inthere :)/>/>/>

EDIT:

I forgot to add this:

Basically a table couldnt care less what you put in it. As long as you keep track of your table contents, it'll work out fine.

You can use this to iterate through the above table sample and figure out what's what:

for i = 1, #tbl do
  if (type(tbl[i]) == "string") then
    print("string value: "..tbl[i])
  elseif (type(tbl[i] == "number") then
    print("number value: "..tbl[i])
  elseif (type(tbl[i] == "function") then
    local fnc = tbl[i]
    fnc() -- This executes the function
  end
end

I find it easier to execute functions in a table, by copying them into a local variable first.

In one build, I had a table strictly containing different functions, that I looped through and had each executed. Sort of a function queue if you want. Each function did something different, but all of them had no parameter, so it felt easier doing it that way. I used that setup to queue up functions while my device was in it's "offline" state. As soon as I switched it to it's "online" state, it would start looping through the function queue and execute each of them in the order I had added them. Later on I decided that it would be cheaper to use string commands and a couple of if-then's to execute the same stuff and stopped using the function table.
Edited on 25 July 2013 - 03:03 AM