Lua-iterators

提供:Dev Guides
移動先:案内検索

Lua-イテレーター

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

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

汎用の_for_イテレータは、コレクション内の各要素のキーと値のペアを提供します。 以下に簡単な例を示します。

array = {"Lua", "Tutorial"}

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

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

1  Lua
2  Tutorial

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

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

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

ステートレスイテレーター

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

ここで、 n 数の2乗を出力する単純な関数を使用して独自の反復子を作成する例を見てみましょう。

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を使用して、関数が呼び出されるたびにインデックスをインクリメントすることでコレクション内の各要素を返す別のメソッドが含まれていることがわかります。

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