Lua-イテレータ

イテレータは、いわゆるコレクションまたはコンテナの要素をトラバースできるようにする構造です。Luaでは、これらのコレクションは多くの場合、配列などのさまざまなデータ構造を作成するために使用されるテーブルを参照します。

イテレータのジェネリック

ジェネリックのためのイテレータはコレクションの各要素のキーと値のペアを提供します。簡単な例を以下に示します。

array = {"Lua", "Tutorial"}

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

上記のコードを実行すると、次の出力が得られます-

1  Lua
2  Tutorial

上記の例では、Luaが提供するデフォルトのipairsイテレータ関数を使用しています。

Luaでは、関数を使用してイテレーターを表します。これらのイテレータ関数の状態維持に基づいて、2つの主要なタイプがあります-

  • ステートレスイテレータ
  • ステートフルイテレータ

ステートレスイテレータ

名前自体から、このタイプのイテレータ関数は状態を保持しないことがわかります。

ここで、の二乗を出力する単純な関数を使用して独自のイテレータを作成する例を見てみましょう。 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関数が機能する方法を模倣するようにわずかに変更できます。以下に示します。

function square(iteratorMaxCount,currentNumber)

   if currentNumber<iteratorMaxCount
   then
      currentNumber = currentNumber+1
      return currentNumber, currentNumber*currentNumber
   end
	
end

function squares(iteratorMaxCount)
   return square,iteratorMaxCount,0
end  

for i,n in squares(3)
do 
   print(i,n)
end

上記のプログラムを実行すると、次の出力が得られます。

1	1
2	4
3	9

ステートフルイテレータ

関数を使用した反復の前の例では、状態が保持されません。関数が呼び出されるたびに、関数に送信された2番目の変数に基づいてコレクションの次の要素が返されます。現在の要素の状態を保持するために、クロージャが使用されます。クロージャは、関数呼び出し間で変数値を保持します。新しいクロージャを作成するには、クロージャ自体とファクトリを含む2つの関数、つまりクロージャを作成する関数を作成します。

ここで、クロージャを使用する独自のイテレータを作成する例を見てみましょう。

array = {"Lua", "Tutorial"}

function elementIterator (collection)

   local index = 0
   local count = #collection
	
   -- The closure function is returned
	
   return function ()
      index = index + 1
		
      if index <= count
      then
         -- return the current element of the iterator
         return collection[index]
      end
		
   end
	
end

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

上記のプログラムを実行すると、次の出力が得られます。

Lua
Tutorial

上記の例では、elementIteratorの内部に別のメソッドがあり、ローカル外部変数のindexとcountを使用して、関数が呼び出されるたびにインデックスをインクリメントすることで、コレクション内の各要素を返していることがわかります。

上記のようにクロージャを使用して独自の関数イテレータを作成でき、コレクションを反復処理するたびに複数の要素を返すことができます。