0Pricing
Lua Academy · レッスン

ジェネリックforとbreak

pairs/ipairsでジェネリックforを使い、breakでループの流れを制御します。

「ジェネリックforとbreak」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。

汎用forプロトコル

Luaの汎用forループは、イテレータ関数とともに動作します。構文はfor vars in iter_func, state, init doです。各反復でLuaはiter_func(state, lastVar)を呼び出し、戻り値をvarsに代入します。最初の戻り値がnilになるとループを終了します。

-- Manual use of next() iterator
local t = {a=1, b=2, c=3}
local key, val = next(t, nil)   -- first entry
while key ~= nil do
  print(key, val)
  key, val = next(t, key)       -- advance
end

すべてのキーを処理するpairs()

pairs(t)は、テーブル内のすべてのキーと値のペアを走査するイテレータを返します。文字列キー、整数キー、混在したキーも含まれます。整数以外のキーの反復順序は未規定です(ハッシュ順)。配列部分とハッシュ部分の両方が含まれます。

local config = {
  host = "localhost",
  port = 8080,
  debug = true,
  [1] = "first",
}

for key, value in pairs(config) do
  print(key, value)
end
-- Prints all 4 entries in any order

配列キーを処理するipairs()

ipairs(t)は、1から始まる整数キーを処理し、最初のnil値で停止します。安全で予測しやすく、順序も保持されます。順序が重要で、最初の空き要素で停止したい配列風テーブルにはipairsを使ってください。

local fruits = {"apple", "banana", "cherry"}

for i, fruit in ipairs(fruits) do
  print(i, fruit)
end
-- 1  apple
-- 2  banana
-- 3  cherry

-- stops at first nil
local t = {10, 20, nil, 40}
for i, v in ipairs(t) do
  print(i, v)  -- only 1,10 and 2,20
end

pairsとipairsの使い分け

用途を使い分けてください。ipairsは順序付きの連続した配列に、pairsは辞書やキーが混在するテーブルに使います。ipairsは最初のnilによる空きで停止しますが、pairsはnilでないすべてのキーを処理します。純粋な配列では、ipairsの方が慣用的です。

local mixed = {10, 20, key="val", 30}

-- ipairs only sees array part in order
print("ipairs:")
for i, v in ipairs(mixed) do
  print(i, v)  -- 1:10, 2:20, 3:30
end

-- pairs sees everything
print("pairs:")
for k, v in pairs(mixed) do
  print(k, v)  -- 1:10, 2:20, 3:30, key:val
end

クロージャによるカスタムイテレータ

クロージャとして独自のイテレータを作成できます。ファクトリ関数は、呼び出されるたびに位置を進める状態付きクロージャを返します。返すものがなくなるとnilを返し、汎用forを停止します。

local function range(from, to, step)
  step = step or 1
  local i = from - step
  return function()
    i = i + step
    if i <= to then return i end
  end
end

for n in range(1, 10, 2) do
  io.write(n .. " ")
end
print()  -- 1 3 5 7 9

イテレータとしてのstring.gmatch

string.gmatch(s, pattern)は、文字列s内でpatternに一致するすべての箇所を順に処理するイテレータを返します。文字列の分割、トークンの抽出、patternのすべての出現箇所の検索などによく使われます。

local sentence = "the quick brown fox"

for word in string.gmatch(sentence, "%a+") do
  print(word)
end
-- the
-- quick
-- brown
-- fox

汎用forでのbreak

汎用forループは、breakを使って途中で終了できます。これは検索に便利です。一致するものが見つかるまで反復し、見つかったらbreakします。breakの後は、endの後にある文から実行が続きます。

local inventory = {
  {name="sword", damage=50},
  {name="shield", armor=30},
  {name="bow", damage=35},
}

local target = "shield"
for i, item in ipairs(inventory) do
  if item.name == target then
    print("Found at index", i)
    break
  end
end

反復中のテーブル変更

pairs()で反復処理している間は、テーブルへのキーの追加や削除を決して行わないでください。動作は未定義です(変更が反映される場合もあれば、スキップされる場合もあります)。テーブルを変更する必要がある場合は、一時的なリストに変更内容を集め、ループ後に適用してください。

local t = {a=1, b=2, c=3, d=4}
local toDelete = {}

-- Collect keys to delete
for k, v in pairs(t) do
  if v % 2 == 0 then
    toDelete[#toDelete+1] = k
  end
end

-- Delete after iteration
for _, k in ipairs(toDelete) do
  t[k] = nil
end
-- t = {a=1, c=3}

列挙パターン

インデックスと値の両方が必要な場合は、両方を提供するipairsを使います。値だけが必要でインデックスを気にしない場合は、インデックスに慣例的な「使用しない」変数名として_を使えます。

local colors = {"red", "green", "blue"}

-- With index
for i, color in ipairs(colors) do
  print(i .. ": " .. color)
end

-- Ignore index with _
for _, color in ipairs(colors) do
  print(color)  -- just the values
end

next()を直接使う

next(t, key)は、テーブルを走査する基盤となる関数です。keyの次にあるキーと値のペアを返し、残りがなければnilを返します。next(t, nil)は最初のエントリを返します。next(t) ~= nilを使うと、要素数を数えるより高速に、テーブルが空でないか確認できます。

local function isEmpty(t)
  return next(t) == nil
end

print(isEmpty({}))       -- true
print(isEmpty({1,2,3}))  -- false
print(isEmpty({a=1}))    -- false

クイックチェック

テーブル内の最初のnilによる空きで停止するイテレータはどれですか?

振り返り:汎用forとbreak

まとめ:

  • pairs(t) — すべてのキーを任意の順序で処理する
  • ipairs(t) — 整数キー1..nを順序どおりに処理し、nilで停止する
  • カスタムイテレータ:停止するためにnilを返すクロージャを返す
  • breakでループを途中終了する
  • pairsの反復中にテーブルを変更しない。変更を集めて後で適用する
  • next(t) == nil — 高速な空テーブル確認

よくある質問

「ジェネリックforとbreak」レッスンは無料ですか?

はい。「ジェネリックforとbreak」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。

「ジェネリックforとbreak」で何を学びますか?

pairs/ipairsでジェネリックforを使い、breakでループの流れを制御します。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Lua Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「ジェネリックforとbreak」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLua Academyレッスンでコードを書いて実行できますか?

はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. if、elseif、else文
  2. whileループとrepeat-untilループ
  3. 数値forループ
  4. ジェネリックforとbreak
← Lua Academyに戻る