lua reference causes problem solution

Foreword: 
The table type in lua is a data structure used to help us create different data types. The use of table is very common in programming, but it will also encounter reference problems.

Goal: 
Improve your own code level by sorting out past problems and combining other people's cases.

Question 1: 
The table type in lua is passed by reference, so you cannot simply copy it through "=" to obtain a new table, otherwise, changing one of the tables will cause the other table to be modified by linkage. The solution is to copy the table through the clone function:

function clone(object)
    local lookup_table = {}
    local function _copy(object)
        if type(object) ~= "table" then
            return object
        elseif lookup_table[object] then
            return lookup_table[object]
        end
        local new_table = {}
        lookup_table[object] = new_table
        for key, value in pairs(object) do
            new_table[_copy(key)] = _copy(value)
        end
        return setmetatable(new_table, getmetatable(object))
    end
    return _copy(object)
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

Question 2: 
When the keys in the table are not consecutive from 1, using the ipairs method to traverse will cause an error because the primary key cannot be found. The solution is to use the pairs traversal instead. The hash values ​​are sorted in order to traverse.

Problem 3: 
The result obtained by the delete operation of the circular table is incorrect. This problem is very subtle and usually not easy to find. The reason for this problem is that deleting the table will cause the structure of the table to be destroyed. The solutions are: 
Method 1. Delete in reverse order

for i=#test,1,-1 do 
    if remove[test[i]] then
        table.remove(test,i)
    end
end
  • 1
  • 2
  • 3
  • 4
  • 5

Method 2, while delete

local i=1
while i<=#test do
    if remove[test[i]] then
        table.remove(test,i)
    else 
        i=i+1
    end
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Method 3, removeItem provided in quick

function table.removeItem(list,item,removeAll)
    local rmCount=0
    fori=1,#list do
        if list[i-rmCount]==item then
            table.remove(list,i - rmCount)
            if removeAll then
                rmCount=rmCount+1
            else
                break
            end
        end
    end
end
for k,v in pairs(remove) do
    table.removeItem(test,k)
end

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325642868&siteId=291194637