美文网首页Lua教程
Lua极简入门(十一)——table类库

Lua极简入门(十一)——table类库

作者: 李小磊_0867 | 来源:发表于2019-11-21 17:17 被阅读0次

table库封装了一些常用的方法,可以在日常的列表操作时提供便利,先看一下table中提供的一些方法。

方法 描述
table.concat(list, sep, i, j) 对数组进行拼接,返回一个字符串
table.insert(list, pos, value) 将元素插入到指定的数组位置
table.move(a1, f, e, t, a2) 将a1数组从f位置开始到e位置结束的元素复制到a2,从a2的t位置开始
table.pack(...) 将参数封包为一个table,数组序列从1开始,同时返回一个n的key,描述参数的数量
table.remove(list, pos) 将指定位置的元素删除
table.sort(list, comp) 对数组进行排序
table.unpack(list, i, j) 将数组的位置i开始到j位置结束,返回数组中的元素

添加与删除

table.insert(t, pos, value)可以将value插入到指定的pos位置,如果pos不是最后位置,需要移动pos以及后续的所有元素,并将value插入到空出的pos位置。如果直接调用table.insert(t, value),则直接将元素value添加到数组的末尾。

local t = {}
table.insert(t, "a")    -- t为空,则a为第一个位置
print(t[1])
-->> a
table.insert(t, 1, "b") -- 将位置1插入元素b,原来的a元素后移指2位置

for i, v in pairs(t) do
    print(i, v)
end
-->> 1  b
-->> 2  a

local a = { "a", "b", "c" }
table.insert(a, 2, "ray")   -- 2位置插入ray,原来的b、c移动到位置3、4
for i, v in pairs(a) do
    print(i, v)
end
-->> 1  a
-->> 2  ray
-->> 3  b
-->> 4  c

删除方法与插入方法类似,table.remove(list, pos),将从pos位置删除元素,并返回该位置的元素,后续的元素会前移;如果不指定pos参数,table.remove(list)将删除最后一个元素。

local t = { "a", "b", "c", "d" }
local d = table.remove(t, 2)
print(d)
-->> b
local d2 = table.remove(t)
print(d2)
--> d

排序

对于数组排序功能较为常见,一般情况如果使用简单数组,可以直接使用table.sort(t),即可实现升序排序(默认为小于操作,即比较函数中第一个元素小于第二个元素);如果复杂table或者要按降序等排序,需要传递第二个参数(排序函数),降序为比较函数中第一个元素大于第二个元素。

local t = { 8, 5, 9, 3, 5, 4, 1 }
table.sort(t)
for i, v in pairs(t) do
    print(i, v)
end
-->> 1  1
-->> 2  3
-->> 3  4
-->> 4  5
-->> 5  5
-->> 6  8
-->> 7  9
local a = { "g", "a", "b", "e", "z", "y" }
table.sort(a)
for i, v in pairs(a) do
    print(i, v)
end
-->> 1  a
-->> 2  b
-->> 3  e
-->> 4  g
-->> 5  y
-->> 6  z

实现降序时,提供一个比较函数,function(a,b),其中a、b分别为数组的两个比较元素。

local a = { "g", "a", "b", "e", "z", "y" }
table.sort(a, function(i, j)    -- 比较函数,降序为第一个元素参数大于第二个元素参数,升序为小于
    return i > j
end)
for i, v in pairs(a) do
    print(i, v)
end
-->> 1  z
-->> 2  y
-->> 3  g
-->> 4  e
-->> 5  b
-->> 6  a

排序还可以对一些复杂的table进行操作,比如有一个对象存储的为学生姓名及分数,按分数从高到低进行排序。

local students = {
    { name = "ray", score = 99 },
    { name = "hh", score = 77 },
    { name = "xx", score = 89 },
    { name = "xy", score = 90 },
    { name = "zs", score = 60 },
    { name = "ls", score = 100 },
}

table.sort(students, function(s1, s2)
    return s1.score > s2.score
end)

for _, v in pairs(students) do
    print(v.name, v.score)
end
-->> ls 100
-->> ray    99
-->> xy 90
-->> xx 89
-->> hh 77
-->> zs 60

移动及封包

table.move(a1, f, e, t, a2),可以按参数指定位置的元素复制到指定起始位置的另外一个table中,类似于数组复制。

这里,我们创建一个数组,长度为4,将从该数组的1位置到3位置共三个元素复制到b数组,b数组从2位置开始接收数据。

local a = { 4, 5, 6, 7 }
local b = {}
table.move(a, 1, 3, 2, b)   -- 这里的位置参数均不能缺省
for i, v in pairs(b) do
    print(i, v)
end
-->> 2  4
-->> 3  5
-->> 4  6

table.pack(...)函数可以将一些散列的参数,封装到一个table中,并将接收的参数个数,以key=n作为最后一个元素插入到table中,之后将该table返回给调用者。

local a = table.pack("ray", { 1, 2, 3 }, "hh", { name = "hh" })
print(a.n)

for i, v in pairs(a) do
    if type(v) ~= "table" then
        print(i, v)
    else
        for j, val in pairs(v) do   -- 这里只是演示,不考虑更多层数组嵌套
            print(i, j, val)
        end
    end
end
-->> 4  --参数长度为4
-->> 1  ray     -- 第一个位置元素
-->> 2  1   1   -- 第二个位置为数组,循环数组,第二个位置为嵌套数组位置
-->> 2  2   2
-->> 2  3   3
-->> 3  hh
-->> 4  name    hh  -- 第四个位置为table,第二个位置为table的key
-->> n  4   -- 参数长度

table.unpack(list, i, j)table.pack(...)功能相反,将一个数组拆解,并返回指定位置的元素。

local a = { "ray", { 1, 2, 3 }, "hh", { name = "hh" } }
local z, x, c, v = table.unpack(a)  -- 返回全部元素
print(z,x,c,v)
-->> ray    table: 0000000000199dc0 hh  table: 0000000000199cc0
local x, c = table.unpack(a, 2, 3)
for i, v in pairs(x) do -- 第二个位置为table
    print(i, v)
end
-->> 1  1
-->> 2  2
-->> 3  3
print(c)    -- 字符串hh
-->> hh

连接

table.concat(list, sep, i, j)函数可以将一个table指定为进行拼接,按照指定的分割符分割,返回一个字符串。在之前的章节中曾经用到过。其中分割符,位置均可省略,分割符省略时,默认为空,位置省略,则默认全部拼接。

local t = { "hello", "lua", ",", "very", "good", "!" }
print(table.concat(t, " "))
-->> hello lua , very good !
print(table.concat(t, " ", 1, 2))   -- 从table的第一个位置开始,到第二个元素进行拼接
-->> hello lua

如果数组中嵌套数组时,直接使用拼接函数将会异常。如上一小节中的实例数组:

local t = { "ray", { 1, 2, 3 }, "hh", { name = "hh" } }
print(table.concat(t, " "))
-->> invalid value (table) at index 2 in table for 'concat'

为了使连接函数更具备通用性,可以对concat进行封装,使用递归调用。(只能处理普通的数组嵌套)

local t = { "ray", { 1, 2, 3 }, "hh", { name = "hh" } }

function concat2(t)
    if type(t) ~= "table" then
        return t
    end
    -- 是数组进行数组拼接,为了无限递归,可以再次循环
    local tmp = {}
    for i = 1, #t do
        tmp[i] = concat2(t[i])
    end
    -- 再次拼接,此时都是基础数组
    return table.concat(tmp, " ")
end

print(concat2(t))
-->> ray 1 2 3 hh

在这个例子中,第四个元素为一个对象table,因此上述方放仍然无法拼接该table。添加对象table的支持拼接方法:

local t = { "ray", { 1, 2, 3 }, "hh", { name = "hh" } }

function concat2(t)
    if type(t) ~= "table" then
        return t
    end
    -- 是数组进行数组拼接,为了无限递归,可以再次循环
    local tmp = {}
    for i, v in pairs(t) do
        if type(i) ~= "number" then
            tmp[#tmp + 1] = i .. "=" .. concat2(v)
        else
            tmp[i] = concat2(v)
        end
    end
    -- 再次拼接,此时都是基础数组
    return table.concat(tmp, " ")
end

print(concat2(t))
-->> ray 1 2 3 hh name=hh

相关文章

  • Lua极简入门(十一)——table类库

    table库封装了一些常用的方法,可以在日常的列表操作时提供便利,先看一下table中提供的一些方法。 方法描述t...

  • Lua极简入门(十二)——string类库

    string类库 这里描述的都是string模块提供的功能,在使用的时候具有两种形式。 之后这里都采用string...

  • Lua极简入门——类型(三)table

    table实现了关联数组,是一种具有特殊索引方式的数组。其具体特点以及使用特性如下。 可以使用整数索引值进行索引,...

  • Lua库函数概览

    Lua库函数概览数学库 table库 字符串库 IO库 os库 调试库

  • lua进阶

    lua官网在线运行代码 table面向对象语法糖 lua对table中的函数调用做了优化,使用起来像类方法,增加了...

  • Lua极简入门(六)——函数

    在完成一些编码工作时,总会有一些相似或者重复的工作。比如在结算工资时,员工的工资不同,但缴纳税、社保等计算是一个相...

  • Lua极简入门(五)——循环

    在编写代码的过程中,总有许多迭代的代码需求,如计算从1连加到10的计算,如果数字足够大,使用表达式计算的方法,将无...

  • Lua极简入门(二)——基础

    lua不需要使用;分割语句,但使用了;进行分割语句,也是合法的。一般情况下,一行代码表示一个语句,当行内出现多个语...

  • Lua极简入门——类型(一)

    nil 该类型,只有一个值nil,主要用于区分其他任何值,它代表了没有任何有效值。当一个变量第一次赋值前,默认为n...

  • Lua极简入门——类型(二)

    string 字符串标识一个字符序列,采用8位编码。Lua字符串是不可变的值,创建后不能再修改内部字符,如果要进行...

网友评论

    本文标题:Lua极简入门(十一)——table类库

    本文链接:https://www.haomeiwen.com/subject/zjitwctx.html