lua-users home
lua-l archive

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

Luis Carvalho wrote:
Wouldn't it be easy, and very low-overhead, to increment and decrement a
count for every add/remove? My countpairs() is O(n) :-(

If you really, really need to know the number of key-value pairs in your table
(which is probably not the case, as Javier suggested), you can try this:

The example below introduced me to the newproxy() method. Unless I am mistaken, in the example below, the use of newproxy() is crucial because otherwise the type of the returned "u" variable will be "table", and setting __len on the metatable of a table does not change the behavior of the # operator.

However, according to old newsgroup postings, newproxy() is an unsupported method. Is there another way to create a userdata object without using C code?


-- hash.lua
local new = function()
  local t = {}
  local n = 0
  local u = newproxy(true)
  local mt = getmetatable(u)
  mt.__index = t
  mt.__newindex = function(o, k, v)
    if t[k] == nil and v ~= nil then -- new key?
      n = n + 1
    elseif t[k] ~= nil and v == nil then -- remove key?
      n = n - 1
    t[k] = v
  mt.__len = function() return n end
  mt.__call = function() return next, t, nil end -- pairs
  return u

module(..., function(mod) setmetatable(mod, {__call = new}) end)

$ lua -i -lhash
Lua 5.1.1  Copyright (C) 1994-2006, PUC-Rio
h = hash()
h.k1 = 10
h.k2 = "hash"
= #h
h.k2 = nil
for k, v in h() do print(k,v) end
k1      10
= #h

It's simple and pure Lua, but I'm not sure it's right. :) I hope you never
need to keep counts on weak tables, as this could get trickier.