knightmade 发表于 2011-12-27 18:11:15

【lua】怎么获得hashtable中的元素个数?

lua里的table可以当作hashtable来用,例如:
local ht = {name="xx", weight=128, location="yangzhou"};
但是,不知道有什么好的办法能得到hashtable内的元素个数?
我目前只能用如下的方法实现:
function count(ht)
    local n = 0;
    for _, v in pairs(ht) do
      n = n + 1;
    end
    return n;
end
注意:#ht对普通数组是有效的,但对hashtable来说,是得不到有效个数的。

北大侠客行MUD,中国最好的MUD

juemengun 发表于 2011-12-27 23:31:50

获得表的最后一个索引的运算符#
获得表的最大数值索引table.maxn
好像没发现其他的

jason 发表于 2011-12-27 23:33:01

table.getn(table)
返回table中元素的个数

juemengun 发表于 2011-12-27 23:38:46

table.getn(tableName)      
等同于操作符 #
作用:得到一个table的大小。
注意:该table的key必须是有序的,索引是从1开始的。

juemengun 发表于 2011-12-27 23:40:11

无序表就是用楼主的方法了

jason 发表于 2011-12-27 23:45:40

那你得实现几个metamethod
newindex,用于给这个table添加新项目的时候
len,用于获取table的长度

你可以在table里包含一个隐藏的字段,每次newindex调用的时候,给这个字段加1,然后调用len的时候返回这个字段的值。

lua的设计很“极限”,呵呵。

wdzyss 发表于 2011-12-28 09:06:51

用#号来获得table的长度只能局限于key是1,2,3,4等类型.
如果key是文字或字符串,lz的方法是不错的.
就是用个泛性for 来计数下,每个key加1

knightmade 发表于 2011-12-28 20:55:35

那你得实现几个metamethod
newindex,用于给这个table添加新项目的时候
len,用于获取table的长度

你可以 ...
jason 发表于 2011-12-27 11:45 PM http://pkuxkx.net/forum/images/common/back.gif

很不幸,你说的这种方法是不行的。首先,看__newindex的定义:
   function settable_event (table, key, value)
       local h
       if type(table) == "table" then
         local v = rawget(table, key)
         if v ~= nil then rawset(table, key, value); return end    -- 当table中key所对应的值不为空时,直接rawset并返回
         h = metatable(table).__newindex
         if h == nil then rawset(table, key, value); return end
       else
         h = metatable(table).__newindex
         if h == nil then
         error(···)
         end
       end
       if type(h) == "function" then
         h(table, key,value)         -- call the handler
       else h = value             -- or repeat operation on it
       end
   end


从上面那句关键的话可以看到,对于ht=nil;这样的语句,如果ht中已经存在key,就不会触发__newindex中的后续处理。
也就是说,只要有删除元素的操作,统计计数就会出错。

再来看len的定义:

   function len_event (op)
       if type(op) == "string" then
         return strlen(op)         -- primitive string length
       elseif type(op) == "table" then
         return #op                -- primitive table length-- 若op是table,则直接返回原生的#op
       else
         local h = metatable(op).__len
         if h then
         -- call the handler with the operand
         return (h(op))
         else-- no handler available: default behavior
         error(···)
         end
       end
   end


从上面的关键的语句可以看出,对于table的#操作符,是无法修改的。

综上所述,lua中的metatable,并不是操作符重载语法。

tankya 发表于 2013-3-1 21:00:20

hzk膜拜中。。

qdz 发表于 2013-3-1 23:22:17

没下文了?求下文呀。
页: [1]
查看完整版本: 【lua】怎么获得hashtable中的元素个数?