• Subject: Re: Unexpected table.remove behaviour.
• From: Patrick Donnelly <batrick@...>
• Date: Tue, 23 Jun 2009 21:44:15 -0600

```Hi,

On Tue, Jun 23, 2009 at 4:03 PM, lostgallifreyan
<lostgallifreyan@gmail.com> wrote:
>
> No, not that one.. :) I read about the fixed problem with out of range indices, this is maybe a different thing.
> If you set an element in an empty table as follows, you can't remove it with table.remove!
>
>    C:\WINDOWS\Desktop>lua
>    Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
>    > x={}
>    > x[40]=5
>    > print(#x)
>    0
>    > print(x[40])
>    5
>    > table.remove(x,40)
>    > print(x[40])
>    5
>    >
>
> Is this intentional? I notice that with Lua v4, you can do it. x[40] will be nil.

It is intentional. table.remove (like table.insert) expects an array
for its table argument. It strictly checks that the value being
removed is within the array's bounds (that is, 1 - #t).

> Here are two different scripts for same purpose of syncing two arrays according to operations carried out on one of them:
>
>    X={0,0,0,0,0,1,1,1,1,2,2,3,4,5,5,5,5,5,6,6,6,6,6,6,6,6,7,8,8,8,8,8,8,8,8,8,9,9,9,9}
>    Y={}
>    for N=#X,1,-1 do
>      Y[N]=N
>      if X[N]==X[N+1] then  table.remove(X,N+1)  table.remove(Y,N+1)  end
>    end
>    print(unpack(X))
>    print(unpack(Y))
>
>    X={0,0,0,0,0,1,1,1,1,2,2,3,4,5,5,5,5,5,6,6,6,6,6,6,6,6,7,8,8,8,8,8,8,8,8,8,9,9,9,9}
>    Y={}
>    for N=getn(X),1,-1 do
>      Y[N]=N
>      if X[N]==X[N+1] then  tremove(X,N+1)  tremove(Y,N+1)  end
>    end
>    for N=1,getn(X) do  print(X[N])  end
>    for N=1,getn(Y) do  print(Y[N])  end
>
> The second one (run on Lua v4) behaves as expected, and desired, the element count is equal in each array and each element is correctly paired across tables as it should be. What do I have to do to get the same behaviour on v5? Note that the manual for v5 says directly that table.remove will remove the element, so this finding is in direct contradiction to the manual, so the point surely needs answering even if it's not new..

Perhaps the manual could be more clear about the array expectation.

I would use this code to get your "sync" behavior above (If I
understand the intent correctly):

X={0,0,0,0,0,1,1,1,1,2,2,3,4,5,5,5,5,5,6,6,6,6,6,6,6,6,7,8,8,8,8,8,8,8,8,8,9,9,9,9}
Y = {}
for i, v in ipairs(X) do
Y[i] = v;
while X[i+1] == v do table.remove(X, i+1); end
end

> PS. I notices 'setn' is deprecated. If I wanted to do it, can it be done some other way, and if so, how?

When I have needed to set the length of a table manually, I have used
key 'n' in the table. An example of how it can be used is gathering
the return values of a function in a table:

function pack (...)
return {n = select("#", ...), ...}
end

Then iterating through all the return values is a simple task. Note
that you can't use "for i, v in ipairs({...}) do ... end" because of
possible nil holes.

--
-Patrick Donnelly

"Let all men know thee, but no man know thee thoroughly: Men freely
ford that see the shallows."

- Benjamin Franklin

```