lua的table库

函数列表:
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 源码中的描述,这里不多介绍;

时间: 2024-08-13 03:34:00

lua的table库的相关文章

Lua整理——table库

table属性 table库是有一些辅助函数构成的,这些函数将table作为数组来操作.其中,有对列表中插入和删除元素的函数,有对数组元素进行排序的函数,还有对链接一个数组中所有字符串的函数. 0.table.getn()Lua 中我们经常假定 array 在最后一个非 nil 元素处结束. 这个传统的约定有一个弊端:我们的 array中不能拥有 nil 元素.对大部分应用来说这个限制不是什么问题,比如当所有的 array 有固定的类型的时候.但有些时候我们的 array 需要拥有 nil 元素

lua的table库中常用的函数

lua提供了一些辅助函数来操作table.例如,从list中insert和remove元素,对array的元素进行sort,或者concatenate数组中的所有strings.下面就详细地讲解这些方法. insert and remove table.insert将一个元素插入到指定位置,例如: t = {1, 2, 3} table.insert(t, 1, 4} t的结果将是{4, 1, 2, 3} insert的第二个参数是可以省略的,这样就会插入到数组的最后,从而不必移动其他元素.同样

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

https://www.cnblogs.com/daochong/p/7363649.html table是Lua语言中的一种重要的数据类型, table 的一些特性简单列举如下: (1).table 是一个“关联数组”,数组的索引可以是数字或者是字符串; (2).table 的默认初始索引一般以 1 开始; (3).table 的变量只是一个地址引用,对 table 的操作不会产生数据影响; (4).table 不会固定长度大小,有新数据插入时长度会自动增长; (5).table 所有索引值都

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

本来这些文章都是在我的个人网站www.zhangyi.studio,目前处在备案状态,暂时访问不了,所以搬到这边.  最近这两天需要弄清楚C++和lua间相互调用和数据传递,废话不多说,直接上过程. 首先是环境环境,Linux(Debian),安装lua,注意需要管理员权限. sudo apt-get install lua5.2 安装完后输入lua或者lua -v 严重是否安装成功以及安装的版本,当然,有了lua运行环境还不够我们还需要安装lua开发库既然我们安装的是lua5.2那么开发库同样

Lua中字符串库中的几个重点函数

前言 在<Lua中的一些库>中也说道了,要对string库的模式匹配进行单独的讲解.对于字符串的处理,对于任何语言的学习来说,都是一个难点,而且也是一个必会的知识点.给你一个字符串,让你按照某种需求进行处理,你不会,那是多么尴尬的一件事情.所以,看完<Lua中的一些库>和这篇文章之后,我争取做到让你在处理字符串时,不再感到捉襟见肘,不再尴尬. 说到Lua中的模式匹配,基本上就是围绕着以下几个函数展开的: find match gsub gmatch 我的总结也就是围绕着上面的四个函

Chapter 20_1 table库

table库是由一些辅助函数构成,把table作为数组来操作,所有的函数都忽略传入参数的那张表中的非数字键. 无论如何,若一个操作需要取表的长度,这个表必须是一个真序列,或是拥有__len元方法. 提供了这样一些功能:从列表中插入和删除元素.对元素排序.连接一个数组中所有字符串. 插入和删除 函数table.insert用于将一个元素插入到一个数组指定位置,然后移动后续元素. 例如数组t = {10,20,30},当调用table.insert(t,1,15)后,t = {15,10,20,30

使用Lua的扩展库LuaSocket用例

目录结构 LuaSocket 是 Lua 的网络模块库,它可以很方便地提供 TCP.UDP.DNS.FTP.HTTP.SMTP.MIME 等多种网络协议的访问操作. 它由两部分组成:一部分是用 C 写的核心,提供对 TCP 和 UDP 传输层的访问支持.另外一部分是用 Lua 写的,负责应用功能的网络接口处理. 一.安装LuaSocket 下面介绍两种安装方法 第一种方法:如果你有安装了 Lua 模块的安装和部署工具 LuaRocks,那么一条指令就能安装部署好 LuaSocket: # lua

lua luna工具库

luna工具库 概述 luna库提供了几个lua开发的常见辅助功能: lua/c++绑定 lua序列化与反序列化 变长整数编码,用于lua序列化,当然也可以方便的用于其他场合 这里把代码编译成了动态库,由于代码非常简单,实际使用时也可以简单的复制文件到自己的工程.lua_archiver引用了lz4库用于数据压缩(lz4.h+lz4.c). lua/c++绑定库(luna.h, luna.cpp)支持Windows, Linux, macOS三平台,默认的luna.h实现需C++14支持.如果编

uLua/toLua加载protobuf转lua的table为bool的解决方法

当我们加载protobuf对应的lua的table的时候,我们使用如下方式来加载 local person_pb = require 'Protol.person_pb' 注意,这个table前面的Protol.这段一定不能去掉,如果去掉了,你加载到的persob_pb将会是一个bool类型的值. 如果加上这个Protol.的话,你才能加载到真正有的数据表. 也许是lua和protobuf工具关联时的一个约定,也许是这样,反正要放在protol文件夹下就能加载到数据表.