当前位置: 首页 > article >正文

八、Lua数组和迭代器

一、Lua数组

数组,就是相同数据类型的元素按一定顺序排列的集合,可以是一维数组和多维数组。
在 Lua 中,数组不是一种特定的数据类型,而是一种用来存储一组值的数据结构。
实际上,Lua 中并没有专门的数组类型,而是使用一种被称为 “table” 的数据结构来实现数组的功能。
Lua 数组的索引键值可以使用整数表示,数组的大小不是固定的。
在 Lua 索引值是以 1 为起始,但你也可以指定 0 开始。

(一)一维数组

一维数组是最简单的数组,其逻辑结构是线性表。
使用索引访问数组元素:

	-- 创建一个数组
	local myArray = {10, 20, 30, 40, 50}
	
	-- 访问数组元素
	print(myArray[1])  -- 输出 10
	print(myArray[3])  -- 输出 30

要计算数组的长度(即数组中元素的个数),你可以使用 # 操作符:

	local myArray = {10, 20, 30, 40, 50}
	-- 计算数组长度
	local length = #myArray
	print(length) -- 输出 5

在这里插入图片描述

array = {"Lua", "Tutorial"}

for i= 0, 2 do
   print(array[i])
end

在这里插入图片描述
正如你所看到的,我们可以使用整数索引来访问数组元素,如果指定的索引没有值则返回 nil。

除此外我们还可以以负数为数组索引值:

array = {}

for i= -2, 2 do
   array[i] = i *2
end

for i = -2,2 do
   print(array[i])
end

在这里插入图片描述

(二)多维数组

多维数组即数组中包含数组或一维数组的索引键对应一个数组。

以下是一个三行三列的阵列多维数组:

-- 初始化数组
array = {}
for i=1,3 do
   array[i] = {}
      for j=1,3 do
         array[i][j] = i*j
      end
end

-- 访问数组
for i=1,3 do
   for j=1,3 do
      print(array[i][j])
   end
end

在这里插入图片描述
不同索引键的三行三列阵列多维数组:

-- 初始化数组
array = {}
maxRows = 3
maxColumns = 3
for row=1,maxRows do
   for col=1,maxColumns do
      array[row*maxColumns +col] = row*col
   end
end

-- 访问数组
for row=1,maxRows do
   for col=1,maxColumns do
      print(array[row*maxColumns +col])
   end
end
1
2
3
2
4
6
3
6
9

二、Lua迭代器

迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。
在 Lua 中迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素。

(一)泛型 for 迭代器

泛型 for 在自己内部保存迭代函数,实际上它保存三个值:迭代函数、状态常量、控制变量。
泛型 for 迭代器提供了集合的 key/value 对,语法格式如下:

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

上面代码中,k, v为变量列表;pairs(t)为表达式列表。
查看以下实例:

array = {"Google", "Runoob"}

for key,value in ipairs(array) 
do
   print(key, value)
end
1  Google
2  Runoob

以上实例中我们使用了 Lua 默认提供的迭代函数 ipairs。

下面我们看看泛型 for 的执行过程:

首先,初始化,计算 in 后面表达式的值,表达式应该返回泛型 for 需要的三个值:迭代函数、状态常量、控制变量;与多值赋值一样,如果表达式返回的结果个数不足三个会自动用 nil 补足,多出部分会被忽略。
第二,将状态常量和控制变量作为参数调用迭代函数(注意:对于 for 结构来说,状态常量没有用处,仅仅在初始化时获取他的值并传递给迭代函数)。
第三,将迭代函数返回的值赋给变量列表。
第四,如果返回的第一个值为nil循环结束,否则执行循环体。
第五,回到第二步再次调用迭代函数
在Lua中我们常常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素。Lua 的迭代器包含以下两种类型:

- 无状态的迭代器
- 多状态的迭代器

(二)无状态的迭代器

无状态的迭代器是指不保留任何状态的迭代器,因此在循环中我们可以利用无状态迭代器避免创建闭包花费额外的代价。
每一次迭代,迭代函数都是用两个变量(状态常量和控制变量)的值作为参数被调用,一个无状态的迭代器只利用这两个值可以获取下一个元素。
这种无状态迭代器的典型的简单的例子是 ipairs,它遍历数组的每一个元素,元素的索引需要是数值。
以下实例我们使用了一个简单的函数来实现迭代器,实现数字 n 的平方:

function iter (a, i)
    i = i + 1
    local v = a[i]
    if v then
       return i, v
    end
end
 
function ipairs (a)
    return iter, a, 0
end

(三)多状态的迭代器

很多情况下,迭代器需要保存多个状态信息而不是简单的状态常量和控制变量,最简单的方法是使用闭包,还有一种方法就是将所有的状态信息封装到 table 内,将 table 作为迭代器的状态常量,因为这种情况下可以将所有的信息存放在 table 内,所以迭代函数通常不需要第二个参数。
以下实例我们创建了自己的迭代器:

array = {"Google", "Runoob"}

function elementIterator (collection)
   local index = 0
   local count = #collection
   -- 闭包函数
   return function ()
      index = index + 1
      if index <= count
      then
         --  返回迭代器的当前元素
         return collection[index]
      end
   end
end

for element in elementIterator(array)
do
   print(element)
end

http://www.kler.cn/a/154019.html

相关文章:

  • 模式:每个服务一个数据库
  • Centos使用人大金仓ksql
  • Vscode/Code-server无网环境安装通义灵码
  • 2.5D视觉——Aruco码定位检测
  • ZSTD 内存泄漏问题
  • “fc-async”提供了基本的异步处理能力
  • 【微软技术栈】数据并行和任务并行中的潜在缺陷
  • (Linux2.6内核)进程调度队列与切换
  • Wireshark使用详解
  • TCP 重传、滑动窗口、流量控制、拥塞控制
  • vue el-button 封装及使用
  • Course2-Week1-神经网络
  • 手写实现一个动态代理框架
  • Ubuntu 安装 MySQL8 配置、授权、备份、远程连接
  • 算法通关村第七关—理解递归(青铜)
  • thinkphp控制器调用脚本
  • SQL Server 2016(基本概念和命令)
  • 2022年4月19日 Go生态洞察:Go开发者调查2021结果分析
  • Android --- Activity/Window/DecorView/ViewRootImpl的创建时机
  • [论文精读]利用大语言模型对扩散模型进行自我修正
  • 2016年五一杯数学建模C题二孩政策问题解题全过程文档及程序
  • 深入理解Linux =~
  • Easy Excel设置表格样式
  • 【Element-ui】Icon 图标与Button 按钮
  • 【代码】基于改进差分进化算法的微电网调度研究matlab
  • 6.1810: Operating System Engineering <Lab2 syscall: System calls>