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

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
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,128评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,316评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,737评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,283评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,384评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,458评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,467评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,251评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,688评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,980评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,155评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,818评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,492评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,142评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,382评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,020评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,044评论 2 352

推荐阅读更多精彩内容