ネストしたテーブルと構造化データ
入れ子構造を作成し、深い階層のフィールドにアクセスします。
「ネストしたテーブルと構造化データ」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。
ネストしたテーブルの基礎
テーブルは値として別のテーブルを含むことができ、任意に深い構造を作れます。ドットやブラケットを連結してネストしたフィールドにアクセスします。途中のテーブルがないとエラーになるため、深いフィールドにアクセスする前に、親テーブルが存在することを必ず確認してください。
local company = {
name = "CoddyKit",
address = {
city = "Istanbul",
country = "Turkey",
zip = "34000"
},
employees = 25
}
print(company.name) -- CoddyKit
print(company.address.city) -- Istanbul
print(company["address"]["zip"]) -- 34000安全な深いアクセス
nil値のフィールドにアクセスすると、"attempt to index a nil value"でクラッシュします。andの短絡評価を使って、t and t.a and t.a.bのように防止できます。コードベースによっては、キーの連鎖を安全にたどるget(t, ...)ヘルパーを定義しています。
local function get(t, ...)
local cur = t
for _, key in ipairs({...}) do
if type(cur) ~= "table" then return nil end
cur = cur[key]
end
return cur
end
local data = {user = {profile = {age = 30}}}
print(get(data, "user", "profile", "age")) -- 30
print(get(data, "user", "missing", "field")) -- nilレコードの配列
よくあるパターンは、テーブル(レコード)の配列です。各要素は名前付きフィールドを持つテーブルです。ipairsで反復し、名前でフィールドにアクセスします。これは、オブジェクトの配列や構造体のリストに相当するLuaのデータ構造です。
local users = {
{id=1, name="Alice", score=95},
{id=2, name="Bob", score=87},
{id=3, name="Carol", score=91},
}
for _, user in ipairs(users) do
print(user.id, user.name, user.score)
endネストしたテーブルの動的な構築
必要に応じて内部テーブルを作成し、ネストした構造を段階的に構築します。内部テーブルに追加する前に、必ずテーブルを初期化してください。よくある間違いは、先に内部テーブルを作成せず、nilをインデックスしようとすることです。
local tree = {}
tree.root = {value = 10}
tree.root.left = {value = 5}
tree.root.right = {value = 15}
tree.root.left.left = {value = 2}
print(tree.root.value) -- 10
print(tree.root.left.value) -- 5
print(tree.root.left.left.value) -- 2JSON風の設定としてのテーブル
Luaのテーブルは、JSONやYAMLと同様に、設定ファイルによく使われます。ファイルはテーブルを返し、アプリケーションはdofile()またはrequire()で読み込みます。ネストしたテーブルで、設定の階層を表現します。
-- config.lua (returned table)
local config = {
server = {
host = "0.0.0.0",
port = 8080,
ssl = false,
},
db = {
host = "localhost",
name = "appdb",
pool_size = 10,
},
logging = { level = "info", file = "/var/log/app.log" }
}
print(config.server.port) -- 8080
print(config.db.pool_size) -- 10隣接リストとしてのグラフ
グラフはテーブルのテーブルとして表現できます。各キーがノードで、その値が隣接ノードのリストです。この隣接リスト表現は、疎グラフでメモリ効率がよく、Luaで扱いやすい方法です。
local graph = {
A = {"B", "C"},
B = {"A", "D"},
C = {"A", "D"},
D = {"B", "C"},
}
-- BFS from A
local visited = {A=true}
local queue = {"A"}
while #queue > 0 do
local node = table.remove(queue, 1)
io.write(node .. " ")
for _, neighbor in ipairs(graph[node]) do
if not visited[neighbor] then
visited[neighbor] = true
queue[#queue+1] = neighbor
end
end
end
print() -- A B C Dネストしたフィールドの変更
親テーブルにアクセスしてキーに値を代入すると、ネストしたフィールドを変更できます。テーブルは参照渡しされるため、テーブルを受け取った関数はその内容を直接変更でき、呼び出し元からも変更が確認できます。
local player = {name="Hero", stats={hp=100, mp=50, atk=20}}
local function takeDamage(p, dmg)
p.stats.hp = math.max(0, p.stats.hp - dmg)
end
takeDamage(player, 35)
print(player.stats.hp) -- 65
player.stats.atk = player.stats.atk + 5
print(player.stats.atk) -- 25ネストしたテーブルのシリアライズ
ネストしたテーブルを文字列に変換すると、デバッグやログ出力に役立ちます。単純な再帰的シリアライザーで任意の深さに対応できますが、循環(循環参照)は処理できません。
local function serialize(val, indent)
indent = indent or 0
local pad = string.rep(" ", indent)
if type(val) ~= "table" then
return tostring(val)
end
local parts = {"{"}
for k, v in pairs(val) do
parts[#parts+1] = pad.." "..tostring(k).."="..serialize(v,indent+1)
end
parts[#parts+1] = pad.."}"
return table.concat(parts, "\n")
end
local data = {x=1, nested={y=2, z=3}}
print(serialize(data))疎行列
2次元行列をそのまま保存すると、大規模で疎な入力ではメモリを無駄に消費します。ネストしたテーブルにゼロ以外のエントリだけを保存し、matrix[row][col] = valueのように表現します。ほとんどの値がゼロの場合、大規模な行列を効率よく表現できます。
local function newMatrix()
return setmetatable({}, {__index=function(t,k)
local row = {}
rawset(t, k, row)
return row
end})
end
local m = newMatrix()
m[1][1] = 5
m[3][7] = 12
m[100][200] = 99
print(m[1][1]) -- 5
print(m[3][7]) -- 12
print(m[2][5]) -- nil (sparse: no value)深い等価性のチェック
テーブルは値ではなく、==で参照によって比較されます。ネストしたテーブルを構造的に比較するには、各キーと値を比較し、ネストしたテーブルに対して再帰する等価性関数を作成します。
local function deepEqual(a, b)
if type(a) ~= type(b) then return false end
if type(a) ~= "table" then return a == b end
for k, v in pairs(a) do
if not deepEqual(v, b[k]) then return false end
end
for k in pairs(b) do
if a[k] == nil then return false end
end
return true
end
print(deepEqual({1,{2,3}},{1,{2,3}})) -- true
print(deepEqual({1,{2,3}},{1,{2,4}})) -- falseクイックチェック
t.aがnilのときにt.a.bへアクセスすると、何が起こりますか?
復習:ネストしたテーブル
まとめ:
- テーブルは任意の深さにネストできます:
t.a.b.c - 深いアクセスを防御します:
t and t.a and t.a.b - テーブルは参照型です。関数は内容を直接変更します
- レコードの配列:
{{name=...},{name=...}} - 疎行列:メモリ効率のためにネストしたテーブルを使います
- 深い等価性には再帰的な比較が必要です
AI チューターと学ぶ Lua — 無料
ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。
- コース
- 40
- レッスン
- 159
よくある質問
「ネストしたテーブルと構造化データ」レッスンは無料ですか?
はい。「ネストしたテーブルと構造化データ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。
「ネストしたテーブルと構造化データ」で何を学びますか?
入れ子構造を作成し、深い階層のフィールドにアクセスします。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Lua Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「ネストしたテーブルと構造化データ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLua Academyレッスンでコードを書いて実行できますか?
はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 配列としてのテーブル
- 辞書としてのテーブル
- pairsとipairsによるテーブルの反復処理
- ネストしたテーブルと構造化データ