I ran across some strange behavior involving looping through a dictionary accessed table a bit ago. I coded up a simple example to showcase it. I believe I know vaguely what is causing the behavior but figured I’d write this post in case anyone has a more accurate explanation for it, a better work-around, and/or just a general awareness that this behavior exists.
Here is the example code snippet:
local list = {}
list["Entry1"] = "Value1"
local itr = 1
print("BEGIN")
for key, value in pairs(list) do
print("itr =", itr,":", key, value)
list["ABC"] = "non-value"
itr = itr + 1
end
print("END")
The output I expected when I found ran into this behavior would have been:
BEGIN
itr = 1 : Entry1 Value1
END
However, the output shows that the loop iterated twice:
BEGIN
itr = 1 : Entry1 Value1
itr = 2 : Entry1 Value1
END
And for that matter, it iterated twice on the same key, value pair.
I know that once this is identified as the problem, there are some fairly simple work-arounds:
- Create a “dummy” copy of the dictionary (perhaps just an array of key names) then iterate over that list instead of the list dictionary which may be modified during iteration
- Initialize an empty “queue” list which will be appended to over the iteration over the list dictionary, then, after iteration, loop over the “queue” which may store functions to be called than then modify the list.
I’m unsure if either of these solutions are ideal however. And still, I’m left wondering a few questions… Why is it that this loop iterates twice on the same key, value pair? I know it must have something to do with adding a new entry on the first iteration. Could this have something to do with the hash-mapping under the hood of Lua dictionaries? Is it possible for the second iteration’s key, value pair to match the key, value appended during the first iteration? Is there a better work-around than one I’ve listed to get around this issue? Any additional information about this behavior would be appreciated.
Thanks,
--East98