Lua Basics: table duplication?

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Lua Basics: table duplication?

William Trenker
Sometimes I want to make a duplicate copy of a table, not just assign
another reference to it.  Is this the standard way:

a={1,2,3, m="m", "n" , o={4}, p = function() end}

b={}
table.foreach(a, function(k,v) b[k]=v end)

Now I can remove elements from b without effecting a.

Thanks,
Bill


Reply | Threaded
Open this post in threaded view
|

Re: Lua Basics: table duplication?

Adrian Sietsma
William Trenker wrote:
Sometimes I want to make a duplicate copy of a table, not just assign
another reference to it.  Is this the standard way:

a={1,2,3, m="m", "n" , o={4}, p = function() end}

b={}
table.foreach(a, function(k,v) b[k]=v end)

close, but you'll still end up with references to child tables, rather than copies. this may be ok for you, otherwise you have to recurse child tables

function clone(node)
  if type(node) ~= "table" then return node end
  local b = {}
  table.foreach(node, function(k,v) b[k]=clone(v) end)
  return b
end

a={1,2,3, m="m", "n" , o={4}, p = function() end}

b=clone(a)

(and that still will only copy references to userdata and functions)

Adrian

Reply | Threaded
Open this post in threaded view
|

Re: Lua Basics: table duplication?

Petite Abeille
Hello,

On Aug 29, 2005, at 06:33, Adrian Sietsma wrote:

  table.foreach(node, function(k,v) b[k]=clone(v) end)

Stylistic question:

What would be the benefit of using a closure in this case?

Wouldn't a simple iterator achieve the same effect?

for k,v in pairs(node) do b[a]=v end

Do the enclosure add anything in this case?

Cheers

--
PA, Onnay Equitursay
http://alt.textdrive.com/


Reply | Threaded
Open this post in threaded view
|

Re: Lua Basics: table duplication?

Adrian Sietsma
PA wrote:
  table.foreach(node, function(k,v) b[k]=clone(v) end)


Stylistic question:

What would be the benefit of using a closure in this case?

Wouldn't a simple iterator achieve the same effect?

for k,v in pairs(node) do b[a]=v end

Do the enclosure add anything in this case?
probably not - i was just cut&paste the original code.

the real answer is cost of iterator vs cost of callback : profile it & see...(i don't know the answer)

Adrian



Reply | Threaded
Open this post in threaded view
|

Re: Lua Basics: table duplication?

Philippe Lhoste
In reply to this post by Adrian Sietsma
Adrian Sietsma wrote:
William Trenker wrote:
Sometimes I want to make a duplicate copy of a table, not just assign
another reference to it.  Is this the standard way:

a={1,2,3, m="m", "n" , o={4}, p = function() end}

b={}
table.foreach(a, function(k,v) b[k]=v end)

close, but you'll still end up with references to child tables, rather than copies. this may be ok for you, otherwise you have to recurse child tables

function clone(node)
   if type(node) ~= "table" then return node end
   local b = {}
   table.foreach(node, function(k,v) b[k]=clone(v) end)
   return b
end

a={1,2,3, m="m", "n" , o={4}, p = function() end}

b=clone(a)

(and that still will only copy references to userdata and functions)

Well, if you kill the original table, these data will continue to live, so I suppose that's the main purpose.
Note that this function is too simplistic, it will gag on self-references:

a.aa = a

clone() with throw a stack overflow...

A number of copy routines has been given on this mailing list, you should check the archives or perhaps the Wiki, and perhaps PiL (Programming in Lua, Roberto's book. Still have to read it...).

Here is the result of my tentative to improve the above code (reformatted to my style...):

function CloneTable(node)
  local visitRef = {}

  local CT
  CT = function (node)
    if type(node) ~= "table" then
--~       print(node)
      return node
    end

     if visitRef[node] then
--~       print"Visited!"
      return nil
     end
     visitRef[node] = true

    return CT(node)
  end

  local subTable = {}
  table.foreach(node,
      function(k, v)
        subTable[k] = CT(v)
      end)
  return subTable
end

But we loose the self-references. Returning 'node' instead of 'nil' seems to work, but with strange results.

--
Philippe Lhoste
--  (near) Paris -- France
--  http://Phi.Lho.free.fr
--  --  --  --  --  --  --  --  --  --  --  --  --  --