# Removing Value From Array With No Gaps

How do I remove values from an array with no gaps?

1 Like

If you know the index of the item you want to remove, you can use table.remove(table, index). This automatically shifts down all other items. But only works if your indexes are numerical.

1 Like

But what if theres multiple of that index? Then it wonâ€™t guarantee to get all of them.

Indexes are unique. If youâ€™re talking about values, those are not guarenteed to be unique (on itâ€™s own).

``````local function removeValuesFromArray(array, value)
for i = #array, 1, -1 do
if array[i] == value then
table.remove(array, i)
end
end
end

local myArray = {1, 6, 2, 8, 4, 8, 3, 8, 2}
removeValuesFromArray(myArray, 8)
print(table.concat(myArray, ", ")) --> 1, 6, 2, 4, 3, 2
``````
12 Likes

The only way i can see as a solution is iterating thru all of them and setting them to nil and then doing another loop to input it into a new table to remove the gaps

If your list of values is small, or if youâ€™re not running the search that often, then that method is just fine.

Edit: didnâ€™t read your last post carefully. table.remove wonâ€™t create any gaps or anythingâ€”it closes the â€śgapâ€ť when it removes an element, so you donâ€™t have to worry about the table having gaps or anything. Osyrisâ€™s method should work fine.

This may be a xy problem, if you disagree please tell me. Iâ€™m not trying to answer the question, but to solve a possible problem youâ€™re experiencing.
If the order of the values doesnâ€™t matter, you should better go off with dictionaries. Since there can only be one key per value, you could map the data of your array as keys, take this example from wiki:

``````local playerScores = {
[game.Players.Telamon] = "Over 9000!",
[game.Players.Roblox] = 1337,
[game.Players.Sorcus] = Enum.DialogTone.Enemy
}
``````

You donâ€™t need to iterate over the table to check if `Roblox` already has a score, because itâ€™s being used as a key. We can better help you if you tell us why you would want to remove values from arrays without â€śgapsâ€ť.

What happens if itâ€™s a large table and you dont wanna any gaps and you dont want to use table remove?

since using table.remove can shift the list down and skipping some elements that should be removed when iterating thru all at once

In that case, if the order of the elements doesnâ€™t matter, you could do the following: swap the deleted element with the last value in the table, then call table.remove(t) without passing an index, which deletes the last value. That way you wonâ€™t have to shift all the elements.

That wouldnâ€™t work because, what happens if the last value of the table also needs to be removed. Swapping it would skip it over.

For example, trying to remove â€ś1â€ť from the a table:

``````local function QuickRemove(tbl, index)
local size = #tbl
tbl[index] = tbl[size]
tbl[size] = nil
end

local Table = {1, 1, 7, 3, 2, 1}

for i, v in pairs(Table) do
if v == 1 then
QuickRemove(Table,i)
end
end

print(table.concat(Table, ", ")) --> 1, 2, 7, 3
``````

Then you can just check if i == #Table-1, in which case you just call table.remove(Table).
Or, even better, iterate from 1 to #Table-1, then leave the last element as an edge case.

EDIT: Actually, youâ€™re right, itâ€™s not quite as simple as I laid it out. Itâ€™s still fairly simple, though.

Hereâ€™s my implementation:

``````local t = {1,1,7,3,2,1}
local Value = 1
do
local i,n = 1,#t
local remove = table.remove
while i<n do
while t[i]==Value do
t[i]= t[n]
remove(t)
n = n-1
end
i = i+1
end
print(table.concat(t,', '))
end``````

The only way i can see as a solution is iterating thru all of them and setting them to nil and then doing another loop to input it into a new table to remove the gaps -Earlier Post

Which way would be more efficient for large tables, yours or mine? Both ways requires iterating thru all the values tho.

All I wanted to show is that you donâ€™t have to create a new table to do what youâ€™re asking. It can all be done in-place.

I donâ€™t think you can get much faster than the code I posted, unless you store the data differently (e.g. a LinkedList). But then you have to make tradeoffs for things like indexing time and memory usage, which arrays are great at doing.

1 Like

Good, because I wasnâ€™t a big fan of creating a whole new table neither.

this works too:

``````local Table = = {1,1,7,3,2,1}
local i = 1

while i <= #Table do
if Table[i] == 1 then
table.remove(Table, i)
else
i = i + 1
end
end

print(table.concat(Table, ", "))
``````

Similar to yours.

I thought we just established that table.remove(t,i) would be inefficient, since it shifts all the elements. That will make it run much much slower.

Although, unless youâ€™re dealing with arrays of 1000 elements or more on a frame-by-frame basis, the increase in speed probably wonâ€™t matter.

You can Mix an Array with a Dictionary, the only draw back is that you canâ€™t send the Full Table with a RemoteObj but you can just Separate the Table and then Re-Combine them later so itâ€™s just Extra work.

``````local Array_Dictionary = {

'Johny',

Johny = true,

'Marry',

['Marry'] = 5,

}

Array_Dictionary[3] = 'Roblox'

Array_Dictionary.Roblox = {}

for i , v in pairs(Array_Dictionary) do

print(i,v)

end

--[[

Output --&gt;&gt;

1 Johny

2 Marry

3 Roblox

Roblox table: 2E12F52C

Johny true

Marry 5

--]]

Array_Dictionary[Array_Dictionary[1]] = nil

table.remove(Array_Dictionary,1)

for i , v in pairs(Array_Dictionary) do

print(i,v)

end

--[[

Output --&gt;&gt;

1 Marry

2 Roblox

Roblox table: 2D5492E4

Marry 5

--]]
``````