博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
lua 迭代器 iterator
阅读量:4958 次
发布时间:2019-06-12

本文共 2471 字,大约阅读时间需要 8 分钟。

Lua 迭代器

迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址

在Lua中迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素。


泛型 for 迭代器

泛型 for 在自己内部保存迭代函数,实际上它保存三个值:迭代函数、状态常量、控制变量。

泛型 for 迭代器提供了集合的 key/value 对,语法格式如下:

 

array = {
"Lua", "Tutorial",key="val",[3]=3,[2]=2,"aaa",[4]=4,[4]=44,[5]=5}for key,value in ipairs(array) do print(key, value)endprint("-------")for key,value in pairs(array)do print(key,value)endlocal tab= { [1] = "a", [3] = "b", [4] = "c" } print("-------")for i,v in pairs(tab) do print(i,v) end print("--------")for i,v in ipairs(tab) do -- 输出 "a" ,k=2时断开 print(i,v) end
 

1 Lua

2 Tutorial
3 aaa
4 44
5 5
-------
1 Lua
2 Tutorial
3 aaa
4 44
key val
5 5

 

 

-------

4 c
1 a
3 b

--------
1 a

 

 

上面例子可得出: ipairs key为整数时才遍历,如果中间突然断开,后面key为整数的也不遍历 table如果有多个相同的key时,取只有value的那个,如果都是[key]=val,取后面那个

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

下面我们看看范性for的执行过程:

  • 首先,初始化,计算in后面表达式的值,表达式应该返回范性for需要的三个值:迭代函数、状态常量、控制变量与多值赋值一样,如果表达式返回的结果个数不足三个会自动用nil补足,多出部分会被忽略
  • 第二,将状态常量和控制变量作为参数调用迭代函数(注意:对于for结构来说,状态常量没有用处,仅仅在初始化时获取他的值并传递给迭代函数)。
  • 第三,将迭代函数返回的值赋给变量列表。
  • 第四,如果返回的第一个值为nil循环结束,否则执行循环体。
  • 第五,回到第二步再次调用迭代函数

在Lua中我们常常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素。Lua 的迭代器包含以下两种类型:

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

无状态的迭代器

无状态的迭代器是指不保留任何状态的迭代器,因此在循环中我们可以利用无状态迭代器避免创建闭包花费额外的代价。

每一次迭代,迭代函数都是用两个变量(状态常量和控制变量)的值作为参数被调用,一个无状态的迭代器只利用这两个值可以获取下一个元素。

这种无状态迭代器的典型的简单的例子是ipairs,他遍历数组的每一个元素。

以下实例我们使用了一个简单的函数来实现迭代器,实现 数字 n 的平方:

function square(iteratorMaxCount,currentNumber)   if currentNumber

以上实例输出结果为:

1    12 4 3 9

上面的square对应是迭代函数,3为状态常量,0为控制变量

 

迭代的状态包括被遍历的表(循环过程中不会改变的状态常量)和当前的索引下标(控制变量),ipairs和迭代函数都很简单,我们在Lua中可以这样实现:

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

当Lua调用ipairs(a)开始循环时,他获取三个值:迭代函数iter、状态常量a、控制变量初始值0;然后Lua调用iter(a,0)返回1,a[1](除非a[1]=nil);第二次迭代调用iter(a,1)返回2,a[2]……直到第一个nil元素。

 

多状态的迭代器

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

 

以下实例我们创建了自己的迭代器:

array = {
"Lua", "Tutorial"}function elementIterator (collection) local index = 0 local count = #collection -- 闭包函数 return function () index = index + 1 if index <= count then -- 返回迭代器的当前元素 return collection[index] end endendfor element in elementIterator(array)do print(element)end

以上实例输出结果为:

LuaTutorial

以上实例中我们可以看到,elementIterator 内使用了闭包函数,实现计算集合大小并输出各个元素。

 

内容参考自:

转载于:https://www.cnblogs.com/cdyboke/p/7748379.html

你可能感兴趣的文章
【Git】标签管理
查看>>
[HNOI2017]大佬
查看>>
『重构--改善既有代码的设计』读书笔记----Hide Delegate
查看>>
1、libgdx简单介绍
查看>>
vuex中的dispatch和commit
查看>>
mybatis实战教程二:多对一关联查询(一对多)
查看>>
NodeMCU文档中文翻译 3 构建固件
查看>>
前端学习☞jquery
查看>>
10分钟搞懂树状数组
查看>>
关于C#的静态类和静态构造函数
查看>>
C#不同窗体间通信,数据传递
查看>>
Windows10下安装Oracle 11g 64位的详细步骤
查看>>
自增运算符:++ 自减运算符:--
查看>>
142. Linked List Cycle II
查看>>
winForm单击用户区可移动窗体,代码控制窗体最大适中
查看>>
linux源
查看>>
配置tomcat服务器时遇到的奇怪现象
查看>>
Android网络多线程断点续传下载
查看>>
Spring Cloud与微服务构建:微服务简介
查看>>
前端跨域之jsonp跨域
查看>>