转自:http://www.runoob.com/lua/lua-iterators.html

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

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


泛型 for 迭代器

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

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

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

  

上面代码中,k, v为变量列表;pairs(t)为表达式列表。

查看以下实例:

array = {"Lua", "Tutorial"}

for key,value in ipairs(array)
do
print(key, value)
end

  

以上代码执行输出结果为:

1  Lua
2 Tutorial

  

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

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

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

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

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

无状态的迭代器

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

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

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

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

function square(iteratorMaxCount,currentNumber) -- 形参是固定的
if currentNumber<iteratorMaxCount
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end for i,n in square,3,0
do
print(i,n)
end

  

以上实例输出结果为:

1    1
2 4
3 9

  

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

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

  

当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
end
end for element in elementIterator(array)
do
print(element)
end

  

以上实例输出结果为:

Lua
Tutorial

  

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

lua 10 迭代器的更多相关文章

  1. Lua基础---迭代器

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

  2. python学习10—迭代器、三元表达式与生成器

    python学习10—迭代器.三元表达式与生成器 1. 迭代器协议 定义:对象必须提供一个next方法,执行该方法或者返回迭代中的下一项,或者返回一个StopIteration异常,以终止迭代(只能往 ...

  3. lua自定义迭代器

    迭代器 http://www.tutorialspoint.com/lua/lua_iterators.htm 迭代器能够让你遍历某个集合或者容器中的每一个元素. 对于lua来说, 集合通常指代 ta ...

  4. python3学习笔记10(迭代器和生成器)

    参考http://www.runoob.com/python3/python3-iterator-generator.html 迭代器 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束 ...

  5. python 10 迭代器和三元运算符

    一.迭代器 1.迭代器协议:对象必须提供一种next方法,执行该方法要么返回迭代中的下一项,要么引起一个stopIteration异常,终止迭代 2.可迭代对象:实现了迭代器协议的对象 3.pytho ...

  6. lua 10进制转换成其它进制table表示

    -- params@num integer -- ~) 默认为10 -- NOTE:先不输出符号 function NumberToArray(num, radix) if type(num) ~= ...

  7. Head First 设计模式 —— 10. 迭代器 (Iterator) 模式

    思考题 public void printMenu() { PancakeHouseMenu pancakeHouseMenu = new PancakeHouseMenu(); ArrayList ...

  8. lua闭包与简易迭代器实现

    1.什么是闭包 闭包,又称闭合函数(closure).通常,如果将一个函数写在另一个函数内,那么这个在内部的函数就可以访问到外部函数中的局部变量,这个特征就是词法域,有些资料上也叫它词法定界.闭包指的 ...

  9. Lua 学习笔记(六)迭代器

    一.迭代器的定义      “迭代器”就是一种可以遍历一种集合中所有元素的机制.在Lua中迭代器以函数的形式表示,即没掉用一次函数,即可返回集合中的“下一个”元素.迭代器的实现可以借助于闭合函数实现, ...

随机推荐

  1. SPA项目之CRUD+表单验证

    1. 表单验证 Form组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则, 并将Form-Item的prop属性设置为需校验的字段名即可 <el-dialog :titl ...

  2. 控制label标签的宽度,不让它换行 label标签左对齐

    1==>控制label标签的宽度.解决字段名太长时,不会换行显示 label-width="100px" label标签的宽度是100px; style="widt ...

  3. 2018CCPC吉林赛区

    传送门 A - The Fool 整除分块即可. B - The World 模拟即可. C - Justice 题意: 给出\(n\)个数\(k_i\),每个数的权值为\(\frac{1}{2^{k ...

  4. ASP.NET CORE HOW TO ADD "ACCESS-CONTROL-EXPOSE-HEADERS" HEADERS?

    services.AddCors(options =>       {                    options.AddPolicy("AnotherPolicy" ...

  5. Python 相对路径和绝对路径--python实战(九)

    一 背景信息 最近在运行python程序的过程中,无意遇到了这个一个问题,在同事那边一直执行ok的程序,到我这里怎么都有个错误,当初报的错误是这样的: FileNotFoundError: [Errn ...

  6. 1+x证书web前端开发jquery专项练习测试题

    javascript程序设计-题库 1.下面哪一种不属于Jquery的选择器? A. 基本选择器 B. 层次选择器 C. 表单选择器 D. 节点选择器 答案: D 2.如果需要匹配包含文本的元素,用下 ...

  7. SpringBoot 和Vue前后端分离入门教程(附源码)

    作者:梁小生0101 juejin.im/post/5c622fb5e51d457f9f2c2381 推荐阅读(点击即可跳转阅读) 1. SpringBoot内容聚合 2. 面试题内容聚合 3. 设计 ...

  8. 朋友想玩下百度的ORC我鼓捣鼓捣thinkphp3集成百度sdk

    他想玩的是文字识别  那就玩下  咱们开始 1 先到百度文字识别  添加个应用  这样就有了APPID API KEY SECRET KEY https://console.bce.baidu.com ...

  9. serf 中去中心化系统的原理和实现

    原文:https://www.infoq.cn/article/principle-and-impleme-of-de-centering-system-in-serf serf 是出自 Hashic ...

  10. 为什么 WPF 的 Main 方法需要标记 STAThread 。

    在编写 WPF 程序时,会发现 Main 方法上方会标记 [STAThread] . 作用:STAThread 标记主线程,也就是 UI 线程是 STA 线程模型. 1 什么是 STA ? 与 STA ...