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

removing a element from a table

Started by Termanater13, 27 January 2014 - 12:05 PM
Termanater13 #1
Posted 27 January 2014 - 01:05 PM
I am looking at ways to remove am element from a table and found table.remove(). my question is there any other way to get the same result, and what is recommended?
CometWolf #2
Posted 27 January 2014 - 01:28 PM
table.remove should only be used if you need to maintain the order of a numerically indexed table. That is, if you have a table indexed from 1-10 and want to remove 5, you should use table.remove. This is because table.remove will move the values 6-10 down one, so you end up with a table indexed from 1-9 instead. Otherwise you should just do the following

tTable[5] = nil
Using table.remove requires more computing power and is thus slower, so it's better to not use it unless nessacary. Not that big of a deal though to be honest, but it's something to keep in mind.
robhol #3
Posted 27 January 2014 - 01:31 PM
That's a little bit unclear. The order is the same in either case, but if you set t[n] = nil in an array that uses numbers as indices, you'll end up with a "hole" - and all the built-in array functions (except pairs) will think the array ends at t[n-1].
Edited on 27 January 2014 - 12:31 PM
surferpup #4
Posted 27 January 2014 - 04:09 PM
Here is an example showing both methods (set element to nil versus using table.remove())


local myTable  = {"one","two","three","four"}

print("Initialize table and print ...")
for i = 1,#myTable do
	print (myTable[i])
end

print()
print("Set table[2]=nil and reprint ...")
myTable[2]= nil
for i = 1,#myTable do
	print (myTable[i])
end

print()
print("Re intialize table, use table.remove() and reprint ...")
myTable  = {"one","two","three","four"}
table.remove(myTable,2)
for i = 1,#myTable do
	print (myTable[i])
end

Output
Initialize table and print…
one
two
three
four

Set table[2]=nil and reprint ...
one

Re intialize table, use table.remove() and reprint …
one
three
four

Note that when setting myTable[2] to nil, the table contains the values (one, nil, three, four). However, the for loop is based on #myTable and stops before the second element – because #myTable will only count sequentially until it encounters a nil value. The values are still there, they just aren't printed in this example do to the limitations of #myTable. Some versions of Lua handle this differently, however, the version of Lua used in ComputerCraft behaves as described in the example.
Edited on 27 January 2014 - 03:18 PM
Bomb Bloke #5
Posted 27 January 2014 - 05:24 PM
It's worth noting that while #myTable will stop counting the length once it hits the first nil index, table.maxn(myTable) will always return the highest index. table.getn(myTable) can usually be expected to do the same, but while faster (as it doesn't do a proper check), it can be led to return the wrong answer (… as it doesn't do a proper check).

That is to say, tables have their own internal counter for keeping track of their highest index. There are some methods of manipulating tables that can result in this value being wrong.

The best way of removing entries from a table or of getting the table's current length depends largely on what you're doing with the table. As the table gets larger, I'd veer towards using eg tTable[5] = nil to remove indexes, while updating my own counter variables to keep track of where the first nil index is and where the last used index is.

None of these methods of getting a table length are of much help when dealing with non-numeric indexes, but then, if you're using those then order isn't a concern at all.
Termanater13 #6
Posted 27 January 2014 - 09:50 PM
just realized that people are talking about numerically listed tables. what if a string was used?
like say:
num[1]='one'
num[2]='two'
num[3]='three'

was
num['one']=1
num['two']=2
num['three']=3
CometWolf #7
Posted 28 January 2014 - 12:13 AM
In that case, just change the value to nil instead of using table.remove. Both ways work, but the former will be faster.