How to Repeat until table is empty?

Basically there are 3 rooms, it randomly picks one, after it picked one, it should remove it from the table and then pick again and again until no rooms are left.

What am I doing wrong?

local LevelOne = workspace.GameLevels.LevelOne
local TableOne = {LevelOne.Room1, LevelOne.Room2, LevelOne.Room3}

function start(player)
	repeat
		for i = 1, #TableOne do
			local Room = TableOne[math.random(#TableOne)]
	
			if TableOne[i] == Room then
				table.remove(TableOne, i)
			end
		end
	until TableOne == {}
	print("Done")
end

Can we see the error? We can trace it.

There is no error, it just keeps repeating

Change to

TableOne[math.random(1,#TableOne)]

Still doesn’t work. Any other ideas why?

If I’m correct, an empty table will return false. So try to use that as an advantage…

I believe it’s because of this condition.

TableOne will never equal {} because {} is an entirely new table that is created with a different reference and so this reference will not equal to the initial TableOne

*Something like printing a table will get you the table reference
Example print:

> print({})
table: 0x17712d4e10846c43
> print({})
table: 0xfe11598a8307b803
> print(#{})
0
> print({}=={})
false

Perhaps you can do this measuring for when the length of the table is 0 meaning there should be nothing in it.

until #TableOne == 0
1 Like

Great point but it’s still not stopping, I believe the table.remove isn’t working properly

I added a teleport function and it keeps teleporting to the same room even though technically it should’ve removed it from the table

Is the function being fired? I don’t see start() anywhere.

There are a few issues with your code, and I’ll explain why step by step:
Issue 1:

for i = 1, #TableOne do
 local Room = TableOne[math.random(#TableOne)]

You’re giving i the value “i” the size of the table “TableOne” and that’s fine, this means the “i” value will take values from 1 to 3 in this case. You’re also assigning “Room” with a random value in “TableOne”, which is perfectly fine, but you have to keep this in mind.

if TableOne[i] == Room then
	table.remove(TableOne, i)
end

Now here’s the main issue, TableOne[i] is the value that’s currently iterating so this means it may never be true since Room could be any other value, therefore the table could never get empty.

Issue 2:

until TableOne == {}

This will always return false, since you’re actually asking the VM whether these 2 tables have the same memory address, the latter is a completely separate table which has no associations with the former one.

Solution:

local LevelOne = workspace.GameLevels.LevelOne
local TableOne = {LevelOne.Room1, LevelOne.Room2, LevelOne.Room3}

function start(player)
	repeat
		local number = math.random(1,#TableOne)
		local Room = TableOne[number]
		table.remove(TableOne, number)

		--Do your stuff here after it gets a room
	until not next(TableOne) --This will make sure the table is 100% empty.
	print("Done")
end
1 Like

Dude you are actually a god haha, thank you so much it worked, I really have no idea what I would’ve done, like no one was even close to this.

Thanks again mate

One more thing I would like to point out is that table.remove actually returns what value corresponds to the index you removed from the table.

With this is in mind, you can change this:

local Room = TableOne[number]
table.remove(TableOne, number)

To just:

local Room = table.remove(TableOne, number)

API Reference: table | Documentation - Roblox Creator Hub

I actually need it though to be separate because I use the picked room in some functions.
Thanks for the suggestion tho

table.remove returns the value of that index. So @R_alatch’s suggestion is valid. As stated in the api document for tables. table | Documentation - Roblox Creator Hub

Removes from array t the element at position pos, returning the value of the removed element.

2 Likes

Thanks for linking the wiki, I’m on mobile and didn’t bother getting the link lol

1 Like