Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

Can't remove Instances of a table?

Asked by 7 years ago

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)

0
Can you add the whole code so we know what line 24 and 27 is? User#5423 17 — 7y
0
You can't remove values from a Read-Only table. That's what GetChildren() does, it returns a read-only table. M39a9am3R 3210 — 7y
0
Actually GetChildren() doesn't return a read-only table, lol ScriptGuider 5640 — 7y
0
That's what it's previous description was. I have it recorded here. https://scriptinghelpers.org/questions/6856/ M39a9am3R 3210 — 7y

1 answer

Log in to vote
1
Answered by 7 years ago
Edited 7 years ago

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.

0
Thanks! maquilaque 136 — 7y
Ad

Answer this question