how to delete all elements in a Lua table?
Asked Answered
R

6

30

How do I delete all elements inside a Lua table? I don't want to do:

t = {}
table.insert(t, 1)
t = {}  -- this assigns a new pointer to t

I want to retain the same pointer to t, but delete all elements within t.

I tried:

t = {}
table.insert(t, 1)
for i,v in ipairs(t) do table.remove(t, i) end

Is the above valid? Or is something else needed?

Rabbit answered 2/2, 2011 at 21:58 Comment(1)
I guess the situation is to empty a table in a function taking it as a parameter. Then the question is a good one, +1. I was at first confused about the word "pointer", which exists in c-code and shouldn't be mentioned in Lua-code. You mean "reference" or something.Gow
S
45
for k in pairs (t) do
    t [k] = nil
end

Will also work - you may have difficulty with ipairs if the table isn't used as an array throughout.

Standardbearer answered 2/2, 2011 at 22:31 Comment(0)
L
29

Table elements insert and remove performance compare

The Table size count 10000000

[1] while and rawset

while #t ~= 0 do rawset(t, #t, nil) end

spent time = 0.677220

[2] next and rawset

for k in next, t do rawset(t, k, nil) end

spent time = 0.344533

[3] ipairs and rawset

for i, v in ipairs(t) do t[i] = nil end

spent time = 0.012450

[4] for, rawset

count = #t
for i=0, count do t[i]=nil end

spent time = 0.009308

Table elemnets insert

[1] table insert function

for i=0, 10000000 do    table.insert(t, i, i) end

spent time = 1.0590489

[2] use #t

for i=0, 10000000 do    t[#t+1] = i end

spent time = 0.703731

[3] for, rawset

for i=0, 10000000 do rawset(t, i, i) end

spent time = 0.100010

result.

Fastest remove : 4

Fastest insert : 3

Lotti answered 13/6, 2015 at 6:12 Comment(1)
This is a thorough and effective answer.Giulio
P
16

easiest and most performant:

for k, _ in pairs(tab) do tab[k] = nil end

What you suggest isn't usable: table.remove shifts the remaining elements to close the hole, and thus messes up the table traversal. See the description for the next function for more info

Protonema answered 2/2, 2011 at 22:27 Comment(0)
S
4

For a faster version that ignores the __pairs metamethod:

local next = next
local k = next(tab)
while k ~= nil do
  tab[k] = nil
  k = next(tab, k)
end

EDIT: As @siffiejoe mentions in the comments, this can be simplified back into a for loop by replacing the pairs call with its default return value for tables: the next method and the table itself. Additionally, to avoid all metamethods, use the rawset method for table index assignment:

for k in next, tab do rawset(tab, k, nil) end
Smoothtongued answered 4/12, 2014 at 6:34 Comment(4)
Or just for k in next,tab do tab[k] = nil endWarrant
According to lua.org/gems/sample.pdf (a Lua optimization guide), this method is surprisingly terrible. The problem is that setting an element to nil typically does not delete it from the table until the next resize. The implementation of next has to search through all the nils before it returns, making this a surprise O(n^2).Gull
@Gull Thanks for pointing that out! My longer while version doesn't suffer from this because next is called with a previous index. @siffiejoe's version is missing that part, so it does the slow version. I'll make an explanatory edit to the answer.Smoothtongued
@Gull actually, I take that back: the "generic for loop" construct automatically takes the return value of the iterator function as the second parameter to the function in the next iteration. So first iteration is k = next(tab, nil), but the next iteration is k = next(tab, k), which avoids the full traversal.Smoothtongued
L
1

#table is the table size and so if t = {1,2,3} then #t = 3

So you can use this code to remove the elements

while #t ~= 0 do rawset(t, #t, nil) end

You will go through the table and remove each element and you get an empty table in the end.

Lotti answered 10/6, 2015 at 2:34 Comment(0)
W
1

Change the variable to anything else and then back to a table, so then it is empty.

t = {1,2,3}
print(t[1])      -- 1
t = "Hello World"
print(t)          -- Hello World
t = {}
print(t[1])       -- nil
Whipperin answered 12/5, 2022 at 7:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.