0Pricing
Lua Academy · レッスン

配列としてのテーブル

table.insertとtable.removeを使って、1始まりの配列を作成・操作します。

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

1始まりの配列

Luaの配列は、1から始まる連続した整数キーを持つテーブルです。これは、0から始まる多くの言語とは異なります。Luaではこの規約が一貫しており、標準ライブラリのすべての関数が1始まりのインデックスを前提としています。範囲外のアクセスはエラーではなく nil を返します。

local colors = {"red", "green", "blue"}
print(colors[1])   -- red
print(colors[2])   -- green
print(colors[3])   -- blue
print(colors[0])   -- nil (no index 0)
print(#colors)     -- 3 (length operator)

table.insertとtable.remove

table.insert(t, val) は末尾に追加します。table.insert(t, pos, val) は指定位置に挿入し、要素を右にずらします。table.remove(t, pos) は pos の要素(デフォルトでは末尾)を削除し、要素を左にずらして、削除した値を返します。

local stack = {}
table.insert(stack, "first")
table.insert(stack, "second")
table.insert(stack, "third")
print(#stack)          -- 3

table.insert(stack, 2, "inserted")
print(stack[2])        -- inserted

local removed = table.remove(stack, 1)
print(removed)         -- first
print(stack[1])        -- inserted

テーブルによるスタック

Luaのテーブルはスタックに最適です。table.insert でプッシュし、table.remove でポップします。どちらもデフォルトではテーブルの末尾に対して動作するため、償却計算量はO(1)です。

local stack = {}

-- Push
table.insert(stack, 10)
table.insert(stack, 20)
table.insert(stack, 30)

-- Pop
print(table.remove(stack))  -- 30
print(table.remove(stack))  -- 20
print(#stack)               -- 1

テーブルによるキュー

キュー(FIFO)はテーブルで実装できますが、table.remove(t, 1) はすべての要素をずらすためO(n)です。高性能なキューでは、2つのポインター(先頭と末尾のインデックス)を使って、要素の移動を避けます。

local head, tail = 1, 0
local queue = {}

local function enqueue(v)
  tail = tail + 1
  queue[tail] = v
end

local function dequeue()
  if head > tail then return nil end
  local v = queue[head]
  queue[head] = nil
  head = head + 1
  return v
end

enqueue("a"); enqueue("b"); enqueue("c")
print(dequeue())  -- a
print(dequeue())  -- b

#長さ演算子

# 演算子は、テーブルの「境界」を返します。これは、t[i] ~= nil かつ t[i+1] == nil となるインデックス i です。空きのないシーケンスでは、配列の長さと同じになります。途中にnilがある場合、# の結果は未定義です。table.pack を使うか、長さを手動で管理してください。

local t = {10, 20, 30, 40, 50}
print(#t)   -- 5

-- Safe for dense arrays
for i = #t, 1, -1 do
  io.write(t[i] .. " ")
end
print()  -- 50 40 30 20 10

配列のスライス

Luaには組み込みのスライス機能はありませんが、table.move(Lua 5.3以降)または手動ループで部分配列を取り出せます。table.move(a1, f, e, t, a2) は、a1[f..e] の要素を a2 の t の位置からコピーします。

local src = {10,20,30,40,50,60}

-- Manual slice
local function slice(t, from, to)
  local result = {}
  for i = from, to do
    result[#result+1] = t[i]
  end
  return result
end

local sub = slice(src, 2, 4)
print(sub[1], sub[2], sub[3])  -- 20  30  40

配列を反転する

両端の要素を中央に向かって入れ替えることで、テーブルをその場で反転できます。これは追加のメモリを使わず、どのLua配列にも適用できる典型的なアルゴリズムです。

local function reverse(t)
  local n = #t
  for i = 1, math.floor(n / 2) do
    t[i], t[n - i + 1] = t[n - i + 1], t[i]
  end
end

local arr = {1, 2, 3, 4, 5}
reverse(arr)
for _, v in ipairs(arr) do
  io.write(v .. " ")
end
print()  -- 5 4 3 2 1

配列を連結する

2つの配列を1つにまとめるには、2つ目の配列をループして、その要素を追加します。Lua 5.3以降では table.move を使うと効率的です。結果は、両方の配列のすべての要素を順番に含む新しいテーブルになります。

local function concat(a, b)
  local result = {}
  for _, v in ipairs(a) do result[#result+1] = v end
  for _, v in ipairs(b) do result[#result+1] = v end
  return result
end

local merged = concat({1,2,3}, {4,5,6})
for i, v in ipairs(merged) do
  io.write(v .. " ")
end
print()  -- 1 2 3 4 5 6

ネストした配列の平坦化

ネストした配列を再帰的に平坦化します。要素がテーブルの場合はその中に再帰し、それ以外の場合は結果に追加します。これは、テーブルを再帰的に走査する自然な応用です。

local function flatten(t, result)
  result = result or {}
  for _, v in ipairs(t) do
    if type(v) == "table" then
      flatten(v, result)
    else
      result[#result+1] = v
    end
  end
  return result
end

local nested = {1, {2, 3}, {4, {5, 6}}, 7}
local flat = flatten(nested)
print(table.concat(flat, ", "))  -- 1, 2, 3, 4, 5, 6, 7

集合としての配列

値をキーとし、その値をtrueにするテーブルを使って集合を実装できます。集合に要素が含まれるかどうかの確認は O(1) です。配列から集合を作ると重複が除去されます。pairsで反復すれば、配列に戻せます。

local function toSet(arr)
  local set = {}
  for _, v in ipairs(arr) do set[v] = true end
  return set
end

local nums = {3,1,4,1,5,9,2,6,5,3}
local set = toSet(nums)
local unique = {}
for k in pairs(set) do unique[#unique+1] = k end
table.sort(unique)
print(table.concat(unique, " "))  -- 1 2 3 4 5 6 9

クイックチェック

table.remove(t)を引数1つだけで呼び出すと、何が起こりますか?

復習:配列としてのテーブル

まとめ:

  • Luaの配列は1始まりのテーブルです
  • 追加と削除にはtable.insert/table.removeを使います
  • 穴のないシーケンスでは#tが長さを返します
  • スタック:末尾から追加・削除します(O(1))
  • キュー:O(n)のシフトを避けるため、headとtailのポインターを使います
  • 要素の有無をO(1)で確認するには、テーブルを集合として使います

よくある質問

「配列としてのテーブル」レッスンは無料ですか?

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

「配列としてのテーブル」で何を学びますか?

table.insertとtable.removeを使って、1始まりの配列を作成・操作します。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

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

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

「配列としてのテーブル」レッスンにはどのくらい時間がかかりますか?

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

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

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

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

  1. 配列としてのテーブル
  2. 辞書としてのテーブル
  3. pairsとipairsによるテーブルの反復処理
  4. ネストしたテーブルと構造化データ
← Lua Academyに戻る