0Pricing
Lua Academy · Lekcja

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"]) -- 34000

Bezpieczny 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"))  -- nil

Tablica 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)
end

Dynamiczne 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)  -- 2

Tabela 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)    -- 10

Graf 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 D

Modyfikowanie 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)  -- 25

Serializacja 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

Na­iwne 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}}))  -- false

Szybkie 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

  1. Tabele jako tablice
  2. Tabele jako słowniki
  3. Iterowanie po tabelach za pomocą pairs i ipairs
  4. Zagnieżdżone tabele i dane strukturalne
← Powrót do Lua Academy