lua-users home
lua-l archive

Re: Documenting Lua gotchas for newbies.

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Dunno if anybody interests this, but this is what I am doing with
tables which are not an array, for which the application freqently
needs the total number of elements.
-----
-- Maintains length of a table.
local CountArray = (function()
 -- Metatable
 local mt = {}
 -- key to native table
 local k_nt = {}
 -- on accessing a nil index.
 mt.__index = function(t, k)
 return t[k_nt][k]
 end
 -- on assigning a new index.
 mt.__newindex = function(t, k, v)
 -- value before
 local vb = t[k_nt][k]
 if v and not vb then
 t._size = t._size + 1
 elseif not v and vb then
 t._size = t._size - 1
 end
 t[k_nt][k] = v
 end
 -- Walks through all entries in any order.
 local function walk(self)
 return pairs(self[k_nt])
 end
 -- returns the count
 local function size(self)
 return self._size
 end
 -- creates a new count array
 local function new()
 -- k_nt is native table, private for this object.
 local o = {_size = 0, walk = walk, size = size, [k_nt] = {} }
 setmetatable(o, mt)
 return o
 end
 -----
 -- public interface
 return {new = new}
end)()
On Fri, Dec 3, 2010 at 2:44 PM, Javier Guerra Giraldez
<javier@guerrag.com> wrote:
> On Fri, Dec 3, 2010 at 7:16 AM, Hisham <hisham.hm@gmail.com> wrote:
>> [*] Of course, this is a minor problem compared to explaining the
>> weird behavior of the # operator. I predict it will be changed to
>> return the actual number of elements of a table sometime around Lua
>> 7.0 (when the argument that not maintaining a counter saves precious
>> memory and processing won't be as compelling)
>
> this has been discussed at length, but i don't think most people
> realize that it's not that easy.
>
> imagine that every table keeps a 'proper' length field, and #t returns it:
>
> t={1,2,3}     => #t = 3
> t[2] = nil      => #t = 3
> t[3] = nil      => #t =.... ?  should be 1, right?
>
> hum... the core would have to scan backwards to skip 2 and set it to 1
>
> now:
> t = {1,2}             => #t = 2
> t[1000000] = 3   => #t = 1000000
> t[500] = 4           => #t = 1000000
> t[1000000] = nil  => #t = ....?  should be 500, right?
>
> now it doesn't seem so cheap to just keep a counter and update _every_
> time you set a member to nil.
>
> think about it,  array-like handling suddenly gets O(n) for some very
> common operations, instead of the current O(1) for most with a single
> O(log n) for a single, relatively low usage operation.
>
>
>
> --
> Javier
>
>

AltStyle によって変換されたページ (->オリジナル) /