1. 程式人生 > >lua 叠代器 iterator

lua 叠代器 iterator

get 部分 idt cnblogs 例子 pan 模板 計算 能夠

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) end print("-------") for key,value in pairs(array) do print(key,value) end local 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<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

上面的square對應是叠代函數,3為狀態常量,0為控制變量

叠代的狀態包括被遍歷的表(循環過程中不會改變的狀態常量)和當前的索引下標(控制變量),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 叠代器

lua 叠代器 iterator