ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   General Authoring Discussion (https://www.esoui.com/forums/forumdisplay.php?f=174)
-   -   Clone vs Copy - any libs for that? (https://www.esoui.com/forums/showthread.php?t=1804)

zgrssd 06/17/14 06:51 AM

Clone vs Copy - any libs for that?
 
I ran into the small issues that tables are generally handed to and from function by reference instead of by value. So I need to channel my inner mad scientist and start cloning.

Some search gave me these code for shallow and deep cloning respectively:
Code:

function copy (t) -- shallow-copy a table
    if type(t) ~= "table" then return t end
    local meta = getmetatable(t)
    local target = {}
    for k, v in pairs(t) do target[k] = v end
    setmetatable(target, meta)
    return target
end

Code:

function clone (t) -- deep-copy a table
    if type(t) ~= "table" then return t end
    local meta = getmetatable(t)
    local target = {}
    for k, v in pairs(t) do
        if type(v) == "table" then
            target[k] = clone(v)
        else
            target[k] = v
        end
    end
    setmetatable(target, meta)
    return target
end

Now I don't understand enough about metatables, tables and lua in general to be certain if that is code right (it looks like it).
And of course it could help to fold both functions into one with a bool switch/int to tell the maximum depth to clone.

Has annybody already written some code for cloning in his library so I don't repeat the same code?

ingeniousclown 06/17/14 08:26 AM

This already exists as a global function implemented by ZO:
lua Code:
  1. function ZO_DeepTableCopy(source, dest)
  2.     dest = dest or {}
  3.    
  4.     for k, v in pairs(source) do
  5.         if type(v) == "table" then
  6.             dest[k] = ZO_DeepTableCopy(v)
  7.         else
  8.             dest[k] = v
  9.         end
  10.     end
  11.    
  12.     return dest
  13. end

This excludes metatables, however, and at a glance, it looks like it will crash on any circular reference.

zgrssd 06/17/14 10:12 AM

Quote:

Originally Posted by ingeniousclown (Post 9468)
This already exists as a global function implemented by ZO:
lua Code:
  1. function ZO_DeepTableCopy(source, dest)
  2.     dest = dest or {}
  3.    
  4.     for k, v in pairs(source) do
  5.         if type(v) == "table" then
  6.             dest[k] = ZO_DeepTableCopy(v)
  7.         else
  8.             dest[k] = v
  9.         end
  10.     end
  11.    
  12.     return dest
  13. end

This excludes metatables, however, and at a glance, it looks like it will crash on any circular reference.

Since I only have data I want to hand out data from my Saved Vars without having any side effects this is ideal.

Wobin 06/18/14 09:09 AM

I used the following in GuildLib

lua Code:
  1. local visitedTables = {}
  2.  
  3. function LibGuildInfo:DeepTableCopy(source, subCall)
  4.     local dest =  {}
  5.    
  6.     for k, v in pairs(source) do
  7.         if type(v) == "table" and not visitedTables[v] then                    
  8.             visitedTables[v] = true
  9.             dest[k] = self:DeepTableCopy(v, true)            
  10.         else
  11.             dest[k] = v
  12.         end
  13.     end
  14.    
  15.     if not subCall then visitedTables = {} end
  16.  
  17.     return dest
  18. end

It kept a list of table references in the external local, and just copied the reference if it had already been traversed.


All times are GMT -6. The time now is 09:08 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2014 - 2022 MMOUI