Iam trying to remove elements in a table which have a certain value
test = {
{
id = 473385593,
deleted = true,
},
{
id = 473385619,
deleted = true,
},
{
id = 473432275,
deleted = false,
},
{
id = 473786710,
deleted = false,
},
}
for index, value in ipairs(test) do
if value.deleted then
table.remove(test, index)
end
end
for _, value in pairs(test) do
print(value.id)
print(value.deleted)
end
I would like that i the output is
473432275
false
473786710
false
But
{
id = 473385619,
deleted = true,
},
is not deleted
So i guess as im iterating over the table to access the value and then do something when deleted == true i remove that element but also reorder the table and so i skip the next element after i call table.remove. At least thats what i figured whats happening.
So how do i remove in lua a tables elements based on their value?
As you figured out already, this snippet
is doing the grave mistake of removing table elements - shifting subsequent elements down - while iterating a table.
for index, value in ipairs(test) do <body> endis roughly equivalent toSo of course if
<body>does atable.remove(test, index), then in the next iterationtest[index]will be the previoustest[index+1]and you will skip an element.I would suggest "filtering" test, and building a new table containing only the elements you want to keep. This would look as follows:
This is asymptotically optimal runtime-wise (linear time). Very often it's cleaner to not mutate the original table; that can lead to surprises.
In case you really want to modify
test, you could iterate in reverse order, e.g. usingfor i = #test, 1, -1 do. Thentable.removewill work fine. But be warned that this has a time complexity bound of O(n²).By keeping a second index you can also do in-place bulk removal of elements in O(n).
Also: Why do you use a "list" here at all? Assuming that you don't care about order, a "hash table" (which lets you remove elements while iterating) would make more sense, given that you have IDs. Consider
then you could just do