通过实例告诉你lua中ipairs到底是怎么遍历的!

news/2024/11/20 4:31:41/

这个的文章挺多的,但是有好几种说法并且不全。有人说是忽略手动设定值,有人说是从1开始数,直到序号断开,还有人给出结果,但是和我实机测试的效果不一样, 所以我自己总结一篇。

经过我的测试和总结得到以下结论:

ipairs是一个专用的遍历函数,主要用于遍历数组,即索引为正整数的表。可以用于遍历表中的所有键值对,其中键仅限于正整数。ipairs遍历和手动设置序号的先后位置无关,优先从非手动设定位置从左向右开始计算非手动设置的索引,计算非手动设置的索引时会跳过手动设定的索引,计算完非手动设定的索引后,寻找手动设定索引,如果手动设定的序号能连上,则算上手动设置的索引连续打印,直到序号断开。

根据以上结论尝试推断以下表输出:

a={[5]="hello",[3]=2,3,4}
for i, v in ipairs(a) doprint(i, v)
end

从非手动设定位置优先开始从左向右计算索引,则为[1]=3,[2]=4,之后寻找手动设定序号,[3]=2。之后继续寻找,只找到5,数字连续性断开,所以只能打印到3的索引。推测结果为[1]=3,[2]=4,[3]=2

和实际结果相符。

以下为推论部分

接下来我们将通过几个实例来推导出具体的原理

例子一

a={[1]="hello",2,[2]=3,4,5}
for i, v in ipairs(a) doprint(i, v)
end

结果如下。

手动设定的[1]和[2]并没有打印出来,所以猜测lua会忽略手动设定值,从2开始计算索引,2索引为1,4索引为2,5索引为3,

例子二

a={[1]="hello",[2]=2,[3]=3}
for i, v in ipairs(a) doprint(i, v)
end

例子一中是忽略手动设定的key值,但是例子二中全部手动设定,得到结果却是全部输出。

因此我认为,lua并不会忽略手动设定的整数值索引,猜测如果全部手动设定且为连续正整数则可以识别,如果其中有不是手动设定的则优先非手动设置的开始计算索引

例子三

a={[1]="hello",[2]=2,3}
for i, v in ipairs(a) doprint(i, v)
end

如图,根据以上推断,优先计算3的索引为1,此时3明明在后面,但结果却是3,2。说明3索引为1,2索引为2,hello的索引断开。这个例子说明序号可以倒序相连。

猜测ipairs是全部元素遍历完后,再寻找连续序号输出,直到序号断开,

例子四

a={[3]="hello",[2]=2,3}
for i, v in ipairs(a) doprint(i, v)
end

倒序输出了3,2,"Hello"。因此可以推断以上假设为真。

因此得出重要结论:ipairs遍历和序号先后位置无关,从非手动设定位置优先从左向右开始计算索引,非手动设定位置索引计算完成后,寻找手动设定索引,如果序号能连上,则算上手动设置的索引连续打印,直到序号断开。

例子五

根据以上推断尝试推断以下表输出:

a={[5]="hello",[3]=2,3,4}
for i, v in ipairs(a) doprint(i, v)
end

从非手动设定位置优先开始从左向右计算索引,则为[1]=3,[2]=4,之后寻找手动设定序号,[3]=2。之后继续寻找,只找到5,数字连续型断开,所以只能打印到3的索引。推测结果为[1]=3,[2]=4,[3]=2

和实际结果相符。

同时根据此结论可以知道例子一a={[1]="hello",2,[2]=3,4,5}的输出为何忽略了[1]=1和[2]=3,因为2,4,5分别占用了1,2,3的索引,接下来要寻找的索引应该是4了,所以忽略掉了[1]和[2],此时若把[1]="Hello"和[2]=3改为[4]="hello",[5]=3则可以打印出2,4,5,"hello",3。

a={[4]="hello",2,[5]=3,4,5}
for i, v in ipairs(a) doprint(i, v)
end

和实际结果相符。

例子七

非手动索引时如何计算的?只计算连续的默认索引还是会跨过手动设置的索引?

a={[2]=0,[4]=0,1,2,3,[5]=6,7,8,9}
for i, v in ipairs(a) doprint(i, v)
end

如果是分块连续索引,则应该是1,2,3后寻找手动索引,得到[4]=0,[5]=6,即1,2,3,0,6

如果是跳过非手动设置索引,则应是,1,2,3,7,8,9

实际结果如下,因此是跳过手动设置的索引进行计算的。


http://www.ppmy.cn/news/24190.html

相关文章

Java 多态

文章目录1、多态的介绍2、多态的格式3、对象的强制类型转换4、instanceof 运算符5、案例:笔记本USB接口1、多态的介绍 多态(Polymorphism)按字面意思理解就是“多种形态”,即一个对象拥有多种形态。 即同一种方法可以根据发送对…

linux 线程

文章目录1、线程的概念1.1、进程 vs 线程1.2、线程的种类2、线程的控制2.1、线程的创建2.2、线程的退出2.3、线程的取消2.4、线程的等待2.5、线程的分离2.5、线程清理函数线程清理函数响应的时机线程清理函数不响应的时机3、线程的同步和互斥3.1、锁机制3.1.1、锁的类型3.1.2、…

求职(JAVA程序员的面试自我介绍)

背景 在找工作的过程中,在面试的环节,大多数面试官首先都会叫你自我介绍一下。一般是3到5分钟内。不过经过我面试的无数的公司还有曾经也面试过大多数的求职者。国内很多的程序员面试都极其不专业。有一种很随心所欲的感觉。所以经常遇到求职者吐槽遇到了…

02- 天池工业蒸汽量项目实战 (项目二)

忽略警告: warnings.filterwarnings("ignore") import warnings warnings.filterwarnings("ignore") 读取文件格式: pd.read_csv(train_data_file, sep\t) # 注意sep 是 , , 还是\ttrain_data.info() # 查看是否存在空数据及数据类型train_data.desc…

Linux内核启动(3,0.11版本)内核启动完成与进入内核main函数

这一部分是在讲解head.s代码,这个代码与bootsect.s和setup.s在同一目录下,但是head.s程序在被编译生成目标文件后会与内核其他程序一起被链接成system模块,位于system模块的最前面开始部分。system模块将被放置在磁盘上setup模块之后开始的扇…

d3.js与echarts对比

D3.js 和 ECharts 是两种常用的数据可视化工具,它们有着不同的优缺点: D3.js: 优点: 功能强大,提供了极高的灵活性和定制性,支持多种图表类型,如柱状图、饼图、散点图、树图、网络图等。 可以…

LSTM已死,Transformer当立(LSTM is dead. Long Live Transformers! ):下

2017 年,Google 在论文 Attention is All you need 中提出了 Transformer 模型,其使用 Self-Attention 结构取代了在 NLP 任务中常用的 RNN 网络结构。而且实验也证明Transformer 在效果上已经完败传统的 RNN 网络。Transformer 的整体模型架构如下图所示。尽管它看起来还是很…

【Hello Linux】 Linux基础命令

作者:小萌新 专栏:Linux 作者简介:大二学生 希望能和大家一起进步! 本篇博客简介:介绍Linux的基础命令 Linux基础命令ls指令lsls -als -dls -ils -sls -lls -nls -Fls -rls -tls -Rls -1总结思维导图pwd指令whoami指令…