Zagnieżdżone tabele i dane strukturalne
Proszę budować zagnieżdżone struktury i uzyskiwać dostęp do głęboko położonych pól.
Zagnieżdżone tabele i dane strukturalne to bezpłatna lekcja Lua Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Lua Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Lua Academy zawiera 4 lekcji w sumie.
Podstawy zagnieżdżonych tabel
Tabele mogą zawierać inne tabele jako wartości, tworząc struktury o dowolnej głębokości. Do zagnieżdżonych pól można uzyskiwać dostęp, łącząc notację kropkową lub nawiasową. Brakujące tabele pośrednie powodują błędy — przed uzyskaniem dostępu do głęboko zagnieżdżonych pól należy zawsze upewnić się, że tabele nadrzędne istnieją.
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"]) -- 34000Bezpieczny dostęp do głęboko zagnieżdżonych pól
Uzyskanie dostępu do pola wartości nil powoduje błąd „attempt to index a nil value”. Można temu zapobiec za pomocą skróconego wartościowania operatora and: t and t.a and t.a.b. W niektórych bazach kodu definiuje się funkcję pomocniczą get(t, ...), która bezpiecznie przechodzi przez łańcuch kluczy.
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")) -- nilTablica rekordów
Częstym wzorcem jest tablica tabel (rekordów). Każdy element jest tabelą z nazwanymi polami. Należy iterować za pomocą ipairs i uzyskiwać dostęp do pól po nazwie. Jest to odpowiednik tablicy obiektów lub listy struktur w 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)
endDynamiczne tworzenie zagnieżdżonych tabel
Zagnieżdżone struktury należy tworzyć stopniowo, tworząc wewnętrzne tabele w razie potrzeby. Przed wstawieniem elementu trzeba zawsze zainicjalizować tabelę. Częstym błędem jest pominięcie utworzenia wewnętrznej tabeli i próba indeksowania wartości 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) -- 2Tabela jako konfiguracja w stylu JSON
Tabele Lua są często używane w plikach konfiguracyjnych, podobnie jak JSON lub YAML. Plik zwraca tabelę, a aplikacja ładuje ją za pomocą dofile() lub require(). Zagnieżdżone tabele reprezentują zagnieżdżone sekcje konfiguracji.
-- 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) -- 10Graf jako lista sąsiedztwa
Graf można reprezentować jako tabelę tabel: każdy klucz oznacza wierzchołek, a jego wartość jest listą sąsiadów. Taka reprezentacja w postaci listy sąsiedztwa oszczędnie wykorzystuje pamięć w przypadku grafów rzadkich i jest łatwa w użyciu w 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 DModyfikowanie zagnieżdżonych pól
Zagnieżdżone pola można modyfikować, uzyskując dostęp do tabeli nadrzędnej i przypisując wartość do klucza. Ponieważ tabele są przekazywane przez referencję, każda funkcja, która otrzymuje tabelę, może modyfikować jej zawartość bezpośrednio — wywołujący zobaczy te zmiany.
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) -- 25Serializacja zagnieżdżonych tabel
Konwersja zagnieżdżonej tabeli na tekst jest przydatna podczas debugowania lub rejestrowania danych. Prosty serializator rekurencyjny obsługuje dowolną głębokość, ale nie poradzi sobie z cyklami (odwołaniami cyklicznymi).
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))Macierze rzadkie
Naiwne przechowywanie macierzy 2D marnuje pamięć w przypadku dużych, rzadkich danych wejściowych. Należy przechowywać tylko niezerowe wpisy w zagnieżdżonej tabeli: matrix[row][col] = value. Pozwala to wydajnie reprezentować ogromne macierze, gdy większość wartości wynosi zero.
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)Sprawdzanie głębokiej równości
Tabele są porównywane za pomocą == przez referencję, a nie według wartości. Aby porównać zagnieżdżone tabele strukturalnie, należy napisać rekurencyjną funkcję równości, która porównuje każdą parę klucz-wartość i wywołuje się rekurencyjnie dla zagnieżdżonych tabel.
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}})) -- falseSzybkie sprawdzenie
Co się stanie podczas uzyskiwania dostępu do t.a.b, jeśli t.a ma wartość nil?
Podsumowanie: zagnieżdżone tabele
Podsumowanie:
- Tabele można zagnieżdżać dowolnie:
t.a.b.c - Należy zabezpieczać głęboki dostęp:
t and t.a and t.a.b - Tabele są typami referencyjnymi — funkcje modyfikują je bezpośrednio
- Tablica rekordów:
{{name=...},{name=...}} - Macierz rzadka: zagnieżdżone tabele zapewniają oszczędność pamięci
- Głęboka równość wymaga porównania rekurencyjnego
Często zadawane pytania
Czy lekcja „Zagnieżdżone tabele i dane strukturalne” jest bezpłatna?
Tak — pełny tekst „Zagnieżdżone tabele i dane strukturalne” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Lua Academy, przejdź na CoddyKit PRO. Kurs Lua Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Zagnieżdżone tabele i dane strukturalne”?
Proszę budować zagnieżdżone struktury i uzyskiwać dostęp do głęboko położonych pól. Ćwiczysz Lua Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Lua Academy?
Nie wymagamy żadnego doświadczenia. Lua Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Zagnieżdżone tabele i dane strukturalne”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Lua Academy?
Tak. Każda lekcja Lua Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Tabele jako tablice
- Tabele jako słowniki
- Iterowanie po tabelach za pomocą pairs i ipairs
- Zagnieżdżone tabele i dane strukturalne