• Chapter 20_1 table库


      table库是由一些辅助函数构成,把table作为数组来操作,所有的函数都忽略传入参数的那张表中的非数字键

      无论如何,若一个操作需要取表的长度,这个表必须是一个真序列,或是拥有__len元方法

      提供了这样一些功能:从列表中插入和删除元素、对元素排序、连接一个数组中所有字符串。

    • 插入和删除

      函数table.insert用于将一个元素插入到一个数组指定位置,然后移动后续元素。

      例如数组t = {10,20,30},当调用table.insert(t,1,15)后,t = {15,10,20,30}

      如果insert函数没有指定位置参数,则会自动添加到数组末尾

      下面示例逐行读取输入,并将所有的行保存在一个数组中:

    t = {}
    for line in io.lines() do
        table.insert(t , line)
    end
    print(#t)        -->读入的行数

      在Lua5.0的老版本中,这样写很正常,但是在最新的版本中,作者建议这样写:

    t[#t+1] = line    --替换insert

      函数table.remove会删除(并返回)数组指定位置上的元素,然后后面的元素前移。

      当没有指定位置参数时,会删除最后一个元素

      通过这两个函数可以很方便地实现栈、队列、双向队列。可以用t = {}来初始化这种结构。

      table.insert(t, x )等价于压入操作。

      table.remove(t) 等价于弹出操作。

      table.insert(t , 1 ,x )在结构的另一端插入一个新元素。

      table.remove(t , 1 )会从这一端删除一个元素。

      后两个操作不是很高效,因为必须移动元素。针对较小的数组可以这样使用。

    • 排序

      另一个有用的数组函数table.sort,之前在高阶函数中提到过。它可以对一个数组进行排序,可以指定一个可选的排序函数。

      这个排序函数必须是一个可以接收两个列表内元素为参数的函数,如果希望第一个参数在排序结果中位于第二个参数值前,就应当返回true。

      再次重现之前的例子:

    network = {
            {name = "arauna",    IP = "210.26.20.30"},
            {name = "brraial",   IP = "210.26.45.33"},
            {name = "lua",       IP = "210.45.34.56"},
            {name = "derain",    IP = "210.26.23.76"},
    }
    table.sort(
                 network,
                 function (a,b)    --这里的a,b参数分别是列表里的两个元素
                   return (a.name < b.name) -- "arauna" < "brraial" 为真,所以下面打印是按照name的升序打印
                 end
              )
    for k,v in pairs(network) do
        print(k,v.name)
    end
    -->1       arauna
    -->2       brraial
    -->3       derain
    -->4       lua                   

      一个常见的错误是试图对一个table的索引进行排序。在table中,索引是一个无序的集合。

    如果对它进行排序,则必须将它们复制到一个数组中,然后再对它进行排序。

    下面演示一个示例:假设要读取一个源文件,并构建一个table记录每个函数并定义它的行号,table如下 :

    lines = {
        luaH_set = 10,
        luaH_get = 24,
        luaH_present = 48,
    }

    现在要按照字母次序打印这些函数名。如果用pairs来遍历table,结果是无序的。由于这些名称是table的key,因此不能对她们进行直接排序。

    应该先放在一个数组中排序:

    a = {}
    for n in pairs(lines) do 
        a[#a+1] = n
    end
    table.sort(a)            --对数组排序,按照默认的小于操作,结果为假,所以打印的是升序排列
    for i , n in ipairs(a) do
        print(n)
    end    
    --> luaH_get
    --> luaH_present
    --> luaH_set

    对于Lua来说,数组也是无序的,它们本质也是table。然而用户知道如何计算索引,因此在访问数组时,只要使用有序的索引,就可以顺序地访问数组。

    这就是为什么必须要使用ipairs而不是pairs来遍历数组的原因。因为前者使用1、2、3....的顺序,后者采用table的原始顺序。

      另一个更高级的方法,写一个迭代器,使它根据table key的次序来进行遍历。同时,还有一个可选的参数f,用于指定某种特殊次序:

    function parisByKeys(t ,f )
        local a = {}
        for n in pairs(t) do a[#a + 1] = n end
        table.sort(a,f)
        local i = 0          --迭代器变量
        return function()    --迭代器函数
            i = i + 1
            return a[i],t[a[i]] --返回原table中的key和value,即函数名和行号
        end
    end

    该函数先将key 排序到一个数组中,然后迭代这个数组,每步返回原table中的key和value。

    通过这个函数就可以很容易地按照字母次序来打印那些函数名了:

    for name , line in pairsByKeys(lines) do
        print(name,line)
    end
    • 连接

      之前也用到过table.connect,它接受一个字符串数组,并返回这些字符串连接后的结果。

    它有一个可选参数,用于指定插到字符串之间的分隔符。

    这个函数另外还接受两个可选参数,用于指定第一个和最后一个要连接的字符串索引。

    下面这个函数是table.connect的一个扩展,它能处理嵌套的字符串数组:

    function rconcat( t )
        if type(t) ~= "table" then return r end
        local res = {}
        for i = 1 , #t do
            res[i] = rconcat(t[i])  --递归调用自己,以此来连接所有可能嵌套的字符串数组。
        end
        return table.concat(res)
    end

    最后调用concat来连接这些结果:

    print(rconcat{{"a",{" nice"}} , " and",{{" long"}, {" list"}}})
    --> a nice and long list
    • 扩展两个有用的函数

      table.pack(...)函数返回一个新表,以1、2、3...为key,参数为值的新表。并将“n”这个域设置为参数的总和。

      这个新表不一定是一个序列。

      table.unpack(list)函数返回列表中的元素,可以加两个参数i ,j 表示要返回的起始索引对应的值。

      等价于:

    return list[i],list[i+1]......,list[j]

      所以,如果不设置i 和j ,就表示默认从1到#list

    以上内容来自:《Lua程序设计第二版》和《Programming in Lua  third edition 》 和 Lua参考手册

  • 相关阅读:
    Linux下配置APUE的编译 报错之后如何处理
    Sed命令的使用详细解释
    Linux下安装xrdp
    CentOS7.1 VNC Server服务配置
    Linux下core文件调试方法
    GDB获取帮助信息
    gdb调试工具学习
    Linux中tftp安装及使用笔记
    CentOS7.3安装Python3.6
    C#语言注释详解
  • 原文地址:https://www.cnblogs.com/daiker/p/5890039.html
Copyright © 2020-2023  润新知