lua table

table示Lua语言中特有的强大武器,是用来存储其他元素的一个实体,通常这些元素都是相互关联的,即使成对元素的一个集合,每对元素都有一个关键字(键名)和一个值组成。在表中可以使用关键字来索引与其唯一对应的值。此外,可使用{}来构造表。

table 类型实现了“关联数组(associative array)”,关联数组是一种具有特殊索引的数组。不仅可以通过整数来所以,还可使用字符串或其他类型的值(除了nil)来索引。

table没有固定大小,可以动态地添加任意数量的元素到一个table中。

table是Lua中主要的数据结构,具有强大的功能。基于table可以以一种简单、统一、高效的方式来表示普通数组、符号表(symbol table)、集合、记录、队列和其他数据结构。

Lua通过table来标识模块(module)、包(package)、对象(object)。例如,io.read表示io模块的read函数,对于Lua而言表示使用字符串read作为key来索引table io。

在Lua中 table 既不是值也不是变量,而是对象。可以将table想象成一种动态分配的对象,程序仅持有一个对它的引用(或指针),Lua不会暗中产生table的副本或创建新的table

Lua中无需声明一个table,事实上可没有办法可以声明tabletable的创建是通过构造表达式(constructor expression)完成的,最简单的构造表达式是{}

$ lua
> a = {}  -- 使用构造表达式创建table

> k = "x"
> a[k] = 20
> a[20] = "great"
> print(a["x"]) -- 20

> k = 20
> print(a[k]) -- "great"

> a["x"] = a["x"] + 1
> print(a["x"]) -- 11

table 永远是匿名的(anonymous),一个持有table的变量与table自身之间没有固定的关联性。

$ lua
> a = {}
> a["x"] = 10
> b = a
> print(b["x"]) -- 10

> b["x"] = 20
> print(a["x"]) -- 20

> a = nil
> b = nil

当程序再也没有对table的引用时,Lua的垃圾收集器(garbage collector)最终会删除该table,并复用它的内存。

table可以用不同类型的索引来访问其值,当需要容纳新条目(entry)时,table会自动增长。

$ lua
> a = {}
> for i=1,1000 do a[i]=i*2 end
> print(a[9])

> a["x"] = 20
> print(a["x"]) -- 20
> print(a["y"]) -- nil

当table的某个元素没有初始化时,它的内容就为nil。

为了表示一条记录,可将字段名作为索引。Lua对于诸如a["name"]的写法提供了一种简便的语法糖(syntactic sugar),可直接使用a.name

$ lua
> a = {}
> a.x = 10
> print(a.x) -- 10
> print(a.y) -- nil

点的写法更明确的暗示读者,将table作为一条记录来使用,每条记录都有一组固定的、预定义的key。而字符串的写法可能暗示了该table会以任何字符串作为key。

$ lua
> a = {}
> x = "y"
> a[x] = 10
> print(a[x]) 
10

> print(a.x) 
nil

> print(a.y) 
10

若要表示一个传统的数组或线性表,仅需以整数作为key来使用table即可。无需声明大小值,直接初始化元素即可。

$ lua
> a = {}
-- 读取10行并存储到一个table中
> for i=1,10 do a[i]=io.read() end

可使用任何值作为table的索引,也可以使用任意数字作为数组索引的初始值,但就Lua的习惯而言,数组通常是以1作为索引的起始值。

Lua5.1中,长度操作符#用于返回一个数组或线性表的最后一个索引值或其大小。

$ lua
> for i=1,#a do print(a[i]) end

对于所有未初始化的元素的索引结果都是nil,Lua将nil作为界定数组结尾的标志。当一个数组有空隙(hole)时,即中间含有nil时,长度操作符会认为这些nil元素就是结尾标记。

若需要处理含有空隙的数组,可使用函数table.maxn(),它将返回一个table的最大正索引数。

$ lua
> a = {}
> a[10000] = 1
> print(table.maxn(a))
10000

表的创建

  • Lua的表是哈希表和数组的结合体
-- 初始化空表
array = {}

-- 删除表元素,置为nil即可。
array["name"] = nil

-- 将函数作为表元素进行添加
tbl = {}
tbl.fn = function()
  print("test")
end 

tbl.fn()
  • table是Lua的一种数据结构,用来创建不同的数据类型,如数组和字典。
  • table 作为关联数组,可使用除nil外的值做数组的索引
  • table 大小是不固定的,可根据自己的需要进行扩容。

定义数组型的表

-- 定义数组型的表
array = {val1, val2, val3}
array = {[1]=val1, [2]=val2, [3]=val3}

-- 使用#获取字符串的长度,在数组中#可获取数组中元素的个数。
print(#array)

-- 数组长度
x = 10
y = 20
z = 30
array = {x, y, z}
print(#array)

-- 数组循环遍历
for i = 1, #array, 1 do
    print(i, array[i])
end
array = {}
table.insert(array, 1, 10)
table.insert(array, 2, 20)
table.insert(array, 3, 30)
table.remove(array, 1)
table.sort(array)
for i = 1, #array, 1 do
    print(i, array[i])
end

-- 创建函数的表作为自定义的函数库
fnlib = {}
fnlib.echo = function(str)
    print(str)
end

fnlib.echo("test")

获取系统变量

for k,v in pairs(_G) do
    print(k,v)
end

当Lua表作为配置

config = {
    game = {
        debug=true
    },
    sound = {
        isBgMusicOpen= true,
        isEffectOpen = false
    },
    texture = {
        PLIST_DIR = "res/plist",
        PACKER_TEXTUER_DIR = "res/images"
    }
}
for k,v in pairs(_ENV) do
    print(k,v)
end

Lua的整体效率是很高的,其中table的实现很巧妙的为此贡献最大。
Lua的Table充当了“数组””和“映射”的双重功能,让Table做数组使用时尽量少效率惩罚。

表的索引

表可以使用字符串作为键,如果使用了则表在自动分配键的时候,会跳过此元素,将键分配给下一个元素。

local tbl = {100, username="alice", 1}
print(tbl[1], tbl[2], tbl.username) -- 100 1 alice

表的操作

local tbl = {"lua", "c", "c++", "c#", "java"}
-- 元素拼接
-- local str = ""
-- str = table.concat(tbl, ",")
-- print( str ) -- lua,c,c++,c#,java
-- 指定索引拼接
-- str = table.concat(tbl, ",", 2, 4)
-- print(str) -- c,c++,c#


-- 插入元素
table.insert(tbl, "js")
print( tbl, #tbl, table.concat(tbl, ","))-- lua,c,c++,c#,java,js

table.insert(tbl, 1, "php")
print( tbl, #tbl, table.concat(tbl,",")) -- php,lua,c,c++,c#,java,js


-- 移除元素
tbl[1] = nil -- 由于元素置空后,占用的位置仍旧存在,不能使用table.concat和ipairs
print( tbl, #tbl)
for i,v in pairs(tbl) do
    print(i,v)
end

-- 移除指定位置的元素
table.remove(tbl, 1)
print(table.concat(tbl, ",")) -- lua,c,c++,c#,java,js

-- 默认移除末尾元素
table.remove(tbl)
print(tbl, #tbl, table.concat(tbl, ",")) -- lua,c,c++,c#,java

表的排序

local tbl = {"lua", "c", "c++", "c#", "java"}

table.insert(tbl, "C")
table.insert(tbl, "PHP")

-- 顺序
table.sort(tbl)
print( table.concat(tbl,",") ) -- C,PHP,c,c#,c++,java,lua

-- 逆序
table.sort(tbl, function(x,y)
    return x > y
end)
print( table.concat(tbl, ",") ) --lua,java,c++,c#,c,PHP,C

表的最值

local tbl = {}

for i=1,10 do
    table.insert(tbl, math.random(1, 100))
end

print(table.concat(tbl, ",")) -- 1,57,20,81,59,48,36,90,83,75

for k,v in pairs( tbl ) do
    print(k,v)
end


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

推荐阅读更多精彩内容

  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 13,513评论 0 38
  • 虽然计算机可以做很多事情,但它不会思考,它需要接受系统化的指令来工作。大部分用户通过应用程序为计算机指派任务,软件...
    JunChow520阅读 7,033评论 0 4
  • 名称 说明 docLua 相关的文档,包括了编译文档、接口文档等 Makefile 编译Lua使用,在...
    一川烟草i蓑衣阅读 1,333评论 0 1
  • 在中餐厅上班几天了,每天开会都要带个小小的记事本,去记一些重要的事情,此外,记事本还记下了许多餐厅的重要信息,...
    洛3阅读 271评论 0 0
  • 汪贵沿江南诗选节||专栏·汪贵沿||2018第4期 原创 2018-04-03 汪贵沿 齐鲁文苑 刊头艺术题字:王...
    宽诗堂阅读 291评论 0 4