Lua 基础之迭代器

lua 数组索引默认从 1 开始。可以指定 0 或者负数开始

1. pairs 和 ipairs 的区别

  • pairs : 可以遍历表中所有的 key 可以返回 nil
  • ipairs: 只遍历值,按照索引升序遍历,索引中断停止遍历。不能返回 nil ,如果遇到 nil 则退出。只遍历到第一个不是整数的 key

例子一:

local table = {
   [1] = "test1",
   [2] = "test2",
   [4] = "test4",
   [55] = "test55"
}

for k, v in pairs( table ) do   
   print(k, v)                 --> 输出所有
end 

for k, v in ipairs( table ) do 
   print(k , v)                --> 输出前两个
end 

例子二:

local table = {"alpha", "beta", [3] = "no", ["two"] = "yes"}

for k, v in pairs( table ) do 
   print(k, v)                  --> 输出所有
end 

for k, v in ipairs( table ) do 
   print(k , v)                 --> 输出前三个,第一个 key 不是整数
end 

2.无状态的迭代器

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

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

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

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

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

function Myipairs (a)
   return iter, a, 0
end

local table = {
   [1] = 1,
   [2] = 2,
   [3] = 3,
   [4] = 4,
   [7] = 7
}

for i,n in ipairs(table) do 
   print(i, n)                
end
--[[
   1  1
   2  2
   3  3
   4  4
]]

3.多状态的迭代器

迭代器需要保存多个状态信息而不是简单的状态常量和控制变量,最简单的方法是使用闭包,还有一种方法就是将所有的状态信息封装到 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