Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Can't remove Instances of a table?

I've got a list with Instances but when I try to remove them, there is an error.

local list = script.Parent:GetChildren()
            for i=1,#list do
               if not list[i]:IsA('BasePart') then
               table.remove(list,i)
        end
end

This is the error:

Script:24: attempt to index field '?' (a nil value) (This code is between line 24 and line 27)

4 comments

0

Can you add the whole code so we know what line 24 and 27 is?

0

You can't remove values from a Read-Only table. That's what GetChildren() does, it returns a read-only table.

0

Actually GetChildren() doesn't return a read-only table, lol

0

That's what it's previous description was. I have it recorded here. https://scriptinghelpers.org/questions/6856/

1 answer

✓ Accepted answer

What's really going on?

The problem is all in how table.remove really works. You see, table.remove not only removes an element from an array, but it also effects the index of every other element after it, moving it down the list by one space. Here's an example:

-- Let's remove "frosting" from this table (index 2)
local array = {"cake","frosting","candle"}

table.remove(array,2) -- Removes "frosting"

Once the example above runs, your table will now look like this to the program:

local array = {"cake","candle"} -- How it really looks now

Opposed to something like this:

local array = {"cake",nil,"candle"} -- Not how it really looks

The table above would be an example of what an array would look like if you set a specific index to nil, without modifying any other element. That would be done by say, doing something like array[index] = nil

Is this a problem?

Well, based on how you're iterating your table, yes. Your for loop runs given the range of 1 through your table's length. But once you remove an element with table.remove, your table's length has shortened because table.remove wants to keep the table as a perfect array.


Once that happens, and your for loops is running past your table's length, at that point you're just running into nil values. It'd basically be the same as saying this:

local t = {1,2,3} -- Table length of 3

for i = 1,4 do -- But iterating it 4 times
	print(t[i])
end

The example above would print this:

1 2 3 nil

and that "nil" value you see at the end is what you're trying to use the "IsA" method on, yielding the error message "attempt to index field "?" (a nil value)"


Solution

Luckily there is a pretty easy solution. You could do either of the following:

  • Use a generic for loop so it won't go past the table's actual length.

  • Just add an and statement within your current for loop, checking to see if list[i] exists before calling a method on it. Here's an example:

local t = {{},{},{}}

for i = 1,#t do
	local v = t[i] -- Makes things easier
	if v and v.IsA then -- Where you'd edit this for ROBLOX objects
		table.remove(t,i)
	end
end

Correcting your current code with either of these solutions should work just fine. If you have any questions, just let me know.

1 comment

0

Thanks!

This discussion is preserved as it was. New answers, comments, and votes are closed.