服务粉丝

我们一直在努力
当前位置:首页 > 科技 >

OpenResty实战-Lua入门-table库

日期: 来源:互联网技能图谱收集编辑:函数

table 库是由一些辅助函数构成的,这些函数将 table 作为数组来操作。下标从 1 开始

在 Lua 中,数组下标从 1 开始计数。

官方解释:Lua lists have a base index of 1 because it was thought to be most friendly for non-programmers, as it makes indices correspond to ordinal element positions.

确实,对于我们数数来说,总是从 1 开始数的,而从 0 开始对于描述偏移量这样的东西有利。而 Lua 最初设计是一种类似 XML 的数据描述语言,所以索引(index) 反应的是数据在里面的位置,而不是偏移量。

在初始化一个数组的时候,若不显式地用键值对方式赋值,则会默认用数字作为下标,从 1 开始。由于在 Lua 内部实际采用哈希表和数组分别保存键值对、普通值,所以不推荐混合使用这两种赋值方式。

local color={first="red", "blue", third="green", "yellow"}

print(color["first"]) --> output: red

print(color[1]) --> output: blue

print(color["third"]) --> output: green

print(color[2]) --> output: yellow

print(color[3]) --> output: nil

从其他语言过来的开发者会觉得比较坑的一点是,当我们把 table 当作栈或者队列使用的时候,容易犯错,追加到 table 的末尾用的是 s[#s+1] = something ,而不是 s[#s] = something ,而且如果这个 something 是一个 nil 的话,会导致这一次压栈(或者入队列) 没有存入任何东西,#s 的值没有变。如果 s = { 1, 2, 3, 4, 5, 6 } ,你令 s[4] = nil ,#s会令你“匪夷所思”地变成 3。table.getn 获取长度

取长度操作符写作一元操作 #。字符串的长度是它的字节数(就是以一个字符一个字节计算的字符串长度) 。

对于常规的数组,里面从 1 到 n 放着一些非空的值的时候,它的长度就精确的为 n,即最后一个值的下标。如果数组有一个“空洞”(就是说,nil 值被夹在非空值之间) ,那么 #t 可能是指向任何一个是 nil 值的前一个位置的下标(就是说,任何一个 nil 值都有可能被当成数组的结束) 。这也就说明对于有“空洞”的情况,table 的长度存在一定的 不可确定性。

local tblTest1 = { 1, a = 2, 3 }

print("Test1 " .. table.getn(tblTest1))

local tblTest2 = { 1, nil }

print("Test2 " .. table.getn(tblTest2))

local tblTest3 = { 1, nil, 2 }

print("Test3 " .. table.getn(tblTest3))

local tblTest4 = { 1, nil, 2, nil }

print("Test4 " .. table.getn(tblTest4))

local tblTest5 = { 1, nil, 2, nil, 3, nil }

print("Test5 " .. table.getn(tblTest5))

local tblTest6 = { 1, nil, 2, nil, 3, nil, 4, nil }

print("Test6 " .. table.getn(tblTest6))

我们使用 Lua 5.1 和 LuaJIT 2.1 分别执行这个用例,结果如下:

# lua test.lua

Test1 2

Test2 1

Test3 3

Test4 1

Test5 3

Test6 1

# luajit test.lua

Test1 2

Test2 1

Test3 1

Test4 1

Test5 1

Test6 1

这一段的输出结果,就是这么 匪夷所思。请问,你以后还敢在 Lua 的 table 中用 nil 值吗?如果你继续往后面加 nil,你可能会发现点什么。你可能认为你发现的是个规律。但是,你千万不要认为这是个规律,因为这是错误的。

不要在 Lua 的 table 中使用 nil 值,如果一个元素要删除,直接 remove,不要用 nil 去代替。table.concat (table [, sep [, i [, j ] ] ])

对于元素是 string 或者 number 类型的表 table,返回 table[i]..sep..table[i+1] ···sep..table[j] 连接成的字符串。填充字符串 sep 默认为空白字符串。起始索引位置 i 默认为1,结束索引位置 j 默认是 table 的长度。如果 i 大于 j,返回一个空字符串。

示例代码

local a = {1, 3, 5, "hello" }

print(table.concat(a)) -- output: 135hello

print(table.concat(a, "|")) -- output: 1|3|5|hello

print(table.concat(a, " ", 4, 2)) -- output:

print(table.concat(a, " ", 2, 4)) -- output: 3 5 hellotable.insert (table, [pos ,] value)

在(数组型) 表 table 的 pos 索引位置插入 value,其它元素向后移动到空的地方。pos 的默认值是表的长度加一,即默认是插在表的最后。

示例代码

local a = {1, 8} --a[1] = 1,a[2] = 8

table.insert(a, 1, 3) --在表索引为1处插入3

print(a[1], a[2], a[3])

table.insert(a, 10) --在表的最后插入10

print(a[1], a[2], a[3], a[4])

-->output

3 1 8

3 1 8 10table.maxn (table)

返回(数组型) 表 table 的最大索引编号;如果此表没有正的索引编号,返回 0。

当长度省略时,此函数通常需要 O(n) 的时间复杂度来计算 table 的末尾。因此用这个函数省略索引位置的调用形式来作 table 元素的末尾追加,是高代价操作。

示例代码

local a = {}

a[-1] = 10

print(table.maxn(a))

a[5] = 10

print(table.maxn(a))

-->output

0 5

此函数的行为不同于 # 运算符,因为 # 可以返回数组中任意一个 nil 空洞或最后一个 nil 之前的元素索引。当然,该函数的开销相比 # 运算符也会更大一些。table.remove (table [, pos])

在表 table 中删除索引为 pos(pos 只能是 number 型) 的元素,并返回这个被删除的元素,它后面所有元素的索引值都会减一。pos 的默认值是表的长度,即默认是删除表的最后一个元素。

示例代码

local a = { 1, 2, 3, 4}

print(table.remove(a, 1)) --删除速索引为1的元素

print(a[1], a[2], a[3], a[4])

print(table.remove(a)) --删除最后一个元素

print(a[1], a[2], a[3], a[4])

-->output

1 2

3 4 nil

4 2

3 nil niltable.sort (table [, comp])

按照给定的比较函数 comp 给表 table 排序,也就是从 table[1] 到 table[n],这里 n 表示 table的长度。 比较函数有两个参数,如果希望第一个参数排在第二个的前面,就应该返回 true,否则返回 false。 如果比较函数 comp 没有给出,默认从小到大排序。

示例代码

local function compare(x, y) --从大到小排序

return x > y --如果第一个参数大于第二个就返回true,否则返回false

end

local a = { 1, 7, 3, 4, 25}

table.sort(a) --默认从小到大排序

print(a[1], a[2], a[3], a[4], a[5])

table.sort(a, compare) --使用比较函数进行排序

print(a[1], a[2], a[3], a[4], a[5])

-->output

1 3 4 7 25

25 7 4 3 1table 其他非常有用的函数

LuaJIT 2.1 新增加的 table.new 和 table.clear 函数是非常有用的。前者主要用来预分配Lua table 空间,后者主要用来高效的释放 table 空间,并且它们都是可以被 JIT 编译的。具体可以参考一下 OpenResty 捆绑的 lua-resty-* 库,里面有些实例可以作为参考。

至此,Lua的Table库就介绍完了,下一篇将介绍Lua的日期时间函数。后续计划内容:

Lua入门+高阶

Nginx

OpenResty

LuaRestyRedisLibrary

LuaCjsonLibrary

PostgresNginxModule

LuaNginxModule

LuaRestyDNSLibrary

LuaRestyLock

stream_lua_module

balancer_by_lua

OpenResty 与 SSL

测试

Web服务

火焰图

OpenResty周边

零碎知识点

相关阅读

  • 网站怎么打开?搜索引擎最便捷!

  • 打开网站需要借助浏览器才可以。在浏览器内输入网站绑定的域名(也就是网址)或者网站服务器的IP地址就可以打开了。网站的直接打开方式网站可以通过直接输
  • 定积分计算的国王法

  • 这里我们所说的“国王法”其实是一个简单的线性变换。似乎它简单得不值一提,但我们觉得这可能是一个挺有用的方法。在英文文献里称之为“King Rule”或
  • 最大似然估计(MLE)入门教程

  • 来源:Deephub Imba本文约1500字,建议阅读9分钟本文解释了 MLE 的工作原理和方式,以及它与 MAP 等类似方法的不同之处。什么是最大似然估计(MLE)最大似然估
  • 原创 | 谷歌JAX 助力科学计算

  • 作者:王可汗审校:陈之炎本文约3500字,建议阅读9分钟本文为你介绍使用谷歌JAX助力科学计算。谷歌最新推出的JAX,官方定义为CPU、GPU和TPU上的NumPy。它具有
  • Vlookup被微软抛弃!新函数FILTER来了,1个顶7个

  • Excel中最强大的查找函数是哪个?相信现在很多人都会提到Vlookup函数,但是它已经将近40岁了,微软都已经把它抛弃了,继任者Xlookup也早就问世,虽然Xlookup很强大,但是我觉得Excel最
  • 搜索引擎算法体系简介-排序和意图篇

  • 本文根据刘老师在2018年DataFun Talk算法架构系列活动“人工智能典型场景算法应用解析”中所分享的《搜索引擎算法体系介绍——排序和意图篇》编辑整理而成,在未改变中心思想
  • Oracle实现金额小写转大写函数

  • 函数代码:create or replace function F_upper_money(p_num in number default null)
    return nvarchar2 is
    /*Ver:1.0 Created By xsb on 2003-8-18 For:
    将金额数字

热门文章

  • OPPO k1的低价高配真实么?网友:不看不知道

  • 近日OPPO一款新机OPPO k1,摒弃了高价低配,就连自家老大哥r17都要怼一下。更是放弃了请代言人,以往的OPPO手机还没出来,各路流量小生,花样美男的代言就先来了。还有线下销售人员的
  • 一招教你手机无限制成为一台新设备

  • 大家平时用手机去注册app,肯定会遇到检测设备异常,交易关闭,等问题 这个都是手机已经不止1-2次注册过此app,不断更换手机仅是一个暂时的方法,却不是长久之计,手机总归会用完
  • 从零开始如何开网店

  • 随着互联网的高速发展,人们的生活发生了翻天覆地的变化,生活节奏越来越快,网购已经成为家家户户生活中离不开的一种购物方式了。网购的发展使得越来越多的人想要涉足电商事业,那

最新文章

  • 订单大涨!新马泰入境政策友好地获苏州人青睐

  • “看到每日增涨的咨询量和预定量,我们旅游人终于迎来春暖花开!”1月8日零时起,随着中国取消入境核酸检测和集中隔离等政策正式生效,出入境机票订单大涨,苏州中国国际旅行社副总经
  • 高血压糖尿病门诊用药保障的报销比例提高至70%

  • 大小新闻1月9日讯(YMG全媒体记者 孙长波 高少帅)在今日上午举行的2023年度首场新闻发布会上,市政协副主席、市发展改革委主任王松杰说,关于提振发展信心巩固向好态势的若干政策