The most optimal thing I can think of looks like this:
-- adding
table.insert(reference_table, "dog")
table['dog'] = #reference_table
-- removing
var idx = table["dog"]
table.remove(reference_table, idx)
for i=idx, #reference_table do
var k = reference_table[i]
table[k] = table[k] - 1
end
table["dog"] = nil
I'm storing the current index of each item as its key, instead of just using true. That lets me remove the item directly. The new issue here is that table.remove moves later items up by one, so those indices have now changed. I use the stored index for the removed element and go over all of the later ones - but only the later ones - and update their index in the main table.
In the end, there's still some looping, but the optimization is that I only go over the items that are known to need changing.
In your case, you're looking for the element, then shuffling all of the later ones back by one (through table.remove). So you're going over each item in the list, guaranteed, every time. (Actually it's worse than that, because you're not using 'break' as soon as you find what you were looking for.)
[EDIT]: Actually, mine goes over the latter part of the list twice when it doesn't necessarily need to. First when removing (it shuffles all items backwards), and again when updating the main list. And #reference_table goes over the whole thing to find out the length... Well, a more accurate version looks like this:
var idx = table["dog"]
while true do
idx = idx + 1
var k = reference_table[idx]
-- end of the list
if k == nil
break
end
-- shuffle items backwards
reference_table[i-1] = k
-- update index in main table
table[k] = table[k] - 1
end
reference_table[idx-1] = nil
table["dog"] = nil
Untested, but it's just merging those three bits together. Finding the end of the list, moving items back, and updating in the main table - all in one single loop.
Just goes to show, though: my original attempt actually performed worse than your original code, even with the missing break. If you added that 'break' in it really wouldn't be an awfully inefficient solution. |