函数列表:
table.insert(table,[ pos,] value)
table.remove(table[, pos])
table.concat(table[, sep[, i[, j]]])
table.sort(table[, comp])


1. insert 和 remove 只能用于数组元素的插入和移出, 进行插入和移出时,会将后面的元素对齐起来。
    所以在 for 循环中进行 insert 和 remove 的时候要注意插入和移除时是否漏掉了某些项:
        local t = {1,2,3,3,5,3,6}
        for i,v in ipairs(t) do
            if v == 3 then
                table.remove(t,i)
            end
        end
        -- 错误,第四个 3 没有被移除,ipairs 内部会维护一个变量记录遍历的位置,remove 掉第三个数字 3 之后,ipairs 下一个返回的值是 5 而不是 3
       
        local t = {1,2,3,3,5,3,6}
        for i=1, #t do
            if t[i] == 3 then
                table.remove(t,i)
                i = i-1
            end
        end
        -- 错误,i=i-1 这段代码没有用,i 的值始终是从 1 到 #t,for 循环里修改 i 的值不起作用
       
        local t = {1,2,3,3,5,3,6}
        for i=#t, 1, -1 do
            if t[i] == 3 then
                table.remove(t,i)
            end
        end
        -- 正确,从后往前遍历
       
        local t = {1,2,3,3,5,3,6}
        local i = 1
        while t[i] do
            if t[i] == 3 then
                table.remove(t,i)
            else
                i = i+1
            end
        end
        -- 正确,自己控制 i 的值是否增加


2. concat 可以将 table 的数组部分拼接成一个字符串,中间用 seq 分隔。
    lua 中字符串的存储方式与 C 不一样,lua 中的每个字符串都是单独的一个拷贝,拼接两个字符串会产生一个新的拷贝,如果拼接操作特别多,就会影响性能:
        local beginTime = os.clock()
        local str = ""
        for i=1, 30000 do
            str = str .. i
        end
        local endTime = os.clock()
        print(endTime - beginTime)
        -- 消耗 0.613 秒,产生了 30000 个字符串拷贝,但只有最后一个是有用的

local beginTime = os.clock()
        local t = {}
        for i=1, 30000 do
            t[i] = i
        end
        local str = table.concat(t, "")
        local endTime = os.clock()
        print(endTime - beginTime)
        -- 消耗 0.024 秒,利用 concat,一次性把字符串拼接出来,只产生了一个字符串拷贝


3. sort 可以将 table 数组部分的元素进行排序,需要提供 comp 函数,comp(a, b) 如果 a 应该排到 b 前面,则 comp 要返回 true 。   
    注意,对于 a==b 的情况,一定要返回 false :
        local function comp(a,b)
            return a <= b
        end
        table.sort(t,comp)
        -- 错误,可能出现异常:attempt to compare number with nil
       
        local function comp(a,b)
            if a == nil or b == nil then
                return false
            end
            return a <= b
        end
        table.sort(t,comp)
        -- 错误,可能出现异常:invalid order function for sorting
        -- 也可能不报这个异常,但结果是错误的;
    之所以 a==b 返回true 会引发这些问题,是因为 table.sort 在实现快速排序时没有做边界检测:
        for (;;) {
          while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {  // 未检测边界, i 会一直增加
            if (i>=u) luaL_error(L, "invalid order function for sorting");
            lua_pop(L, 1);
          }
          while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {  // 未检测边界, j 会一直减少
            if (j<=l) luaL_error(L, "invalid order function for sorting");
            lua_pop(L, 1);
          }
          if (j<i) {
            lua_pop(L, 3);
            break;
          }
          set2(L, i, j);
        }
    看以上代码,如果 a==b 时返回 true 且边界上的几个值是相等的话, sort_comp 就无法阻止 i 继续增长,直到超出边界引发异常 attempt to compare number with nil;即使我们对 a 和 b 进行非空判断,也会因为 i 超过边界而引发异常 invalid order function for sorting
    快速排序是什么,lua 如何实现快速排序,可以参考 lua 源码中的描述,这里不多介绍;

lua的table库的更多相关文章

  1. Lua 之table库

    标准table库 table.concat(table, sep,  start, end) concat是concatenate(连锁, 连接)的缩写,table.concat()函数列出参数中指定 ...

  2. Lua整理——table库

    table属性 table库是有一些辅助函数构成的,这些函数将table作为数组来操作. 当中.有对列表中插入和删除元素的函数,有对数组元素进行排序的函数.还有对链接一个数组中全部字符串的函数. 0. ...

  3. lua的table库中经常使用的函数

    lua提供了一些辅助函数来操作table. 比如,从list中insert和remove元素,对array的元素进行sort.或者concatenate数组中的全部strings.以下就具体地解说这些 ...

  4. lua的table库中的常用函数总结

    table是Lua语言中的一种重要的数据类型, table 的一些特性简单列举如下: (1).table 是一个“关联数组”,数组的索引可以是数字或者是字符串; (2).table 的默认初始索引一般 ...

  5. Chapter 20_1 table库

    table库是由一些辅助函数构成,把table作为数组来操作,所有的函数都忽略传入参数的那张表中的非数字键. 无论如何,若一个操作需要取表的长度,这个表必须是一个真序列,或是拥有__len元方法. 提 ...

  6. Lua 设置table为只读属性

    项目中部分只读表易被人误改写,故决定在非线上环境里对这些表附加只读属性,方便在出现误改写的时候抛出lua错误,最终版代码如下: --[[-------------------------------- ...

  7. Linux下C/C++和lua交互-Table

    本来这些文章都是在我的个人网站www.zhangyi.studio,目前处在备案状态,暂时访问不了,所以搬到这边.  最近这两天需要弄清楚C++和lua间相互调用和数据传递,废话不多说,直接上过程. ...

  8. c++获取lua嵌套table某属性的值

    开发环境:vs2012 lua版本:LuaJIT-2.0.2 lua文件作为配置文件,c++读取这个配置. lua配置结构如下 SceneConfig = { [] = { name =}, [] = ...

  9. lua luna工具库

    luna工具库 概述 luna库提供了几个lua开发的常见辅助功能: lua/c++绑定 lua序列化与反序列化 变长整数编码,用于lua序列化,当然也可以方便的用于其他场合 这里把代码编译成了动态库 ...

随机推荐

  1. Statusbar

    Main window The QtGui.QMainWindow class provides a main application window. This enables to create a ...

  2. 如何设置mysql登陆密码?

    此情况用于mysql密码为空. 命令如下: Mysqladmin –uroot password root1234 Root是用户名,root1234是新设置的密码

  3. 深入理解 Linux 内存管理

    1. 内存地址 以Intel的中央处理器为例,Linux 32位的系统中.物理内存的基本单位是字节(Byte),1个字节有8个二进制位. 每一个内存地址指向一个字节,内存地址加1后得到下一个字节的地址 ...

  4. spring boot更换日志为log4j2

    <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...

  5. Linux 文件系统的目录定义

    目录名称 应放置文件的内容 /boot 开机所需文件——内核,开机菜单及所需配置文件等 /dev 任何设备与接口都以文件形式存放在此目录 /etc 配置文件 /home 用户主目录 /bin 单用户维 ...

  6. 通俗的理解HTTPS以及SSL中的证书验证

    一.HTTPS的安全性体现在哪 HTTP(超文本传输协议,Hyper Text Transfer Protocol)是我们浏览网站信息传输最广泛的一种协议.HTTPS(Hyper Text Trans ...

  7. js出现Syntax error on token "catch", Identifier expected

    本文转自:http://blog.csdn.net/u011159417/article/details/73916676 项目中需要使用jQuery,因此下载了jQuery的js包jquery-3. ...

  8. java 快速求素数

    package test ; import java.util.Scanner ; public class hello { public static void main(String [] arg ...

  9. [转]浅析360的危害 & 我为什么推荐卸载360

    http://blog.eqoe.cn/posts/fuck-360-ass.html 首先放一些证据: [视频证据]360安全浏览器暗设后门 360SE.BackDoor.超清可用WMP播放 密码: ...

  10. 解释-DNS,A记录,CNAME记录,域名转向,SRV记录,TTL值,泛域名与泛解析,域名绑定

    http://www.lihongye.net/post/dns.html DNS DNS,Domain Name System或者Domain Name Service(域名系统或者域名服务).域名 ...