Lua Academy · Lektion

Indlejrede tabeller og strukturerede data

Opbyg indlejrede strukturer, og tilgå felter på dybe niveauer.

Lektion 4 af 412 trin

Indlejrede tabeller og strukturerede data er en gratis Lua Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Lua Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Lua Academy-kurset indeholder 4 lektioner i alt.

Grundlæggende om indlejrede tabeller

Tabeller kan indeholde andre tabeller som værdier, så der kan oprettes strukturer med vilkårligt mange niveauer. Tilgå indlejrede felter ved at kæde punkt- eller kantet parentes-notation sammen. Manglende mellemliggende tabeller giver fejl — sørg altid for, at overordnede tabeller findes, før du tilgår dybe felter.

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

Sikker dyb adgang

Det giver et nedbrud at tilgå et felt på en nil-værdi med fejlen "attempt to index a nil value". Beskyt dig mod dette med kortslutning ved hjælp af and: t and t.a and t.a.b. Nogle kodebaser definerer en hjælpefunktion get(t, ...), der gennemløber en kæde af nøgler på en sikker måde.

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

Array med poster

Et almindeligt mønster er et array af tabeller (poster). Hvert element er en tabel med navngivne felter. Gennemløb med ipairs, og tilgå felterne efter navn. Dette svarer i Lua til et array af objekter eller en liste med strukturer.

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

Dynamisk opbygning af indlejrede tabeller

Opbyg indlejrede strukturer trinvis ved at oprette indre tabeller efter behov. Initialisér altid en tabel, før du indsætter noget i den. En almindelig fejl er at glemme at oprette den indre tabel først og derefter forsøge at indeksere 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

Tabel som JSON-lignende konfiguration

Lua-tabeller bruges ofte til konfigurationsfiler på samme måde som JSON eller YAML. Filen returnerer en tabel, og programmet indlæser den med dofile() eller require(). Indlejrede tabeller repræsenterer indlejrede konfigurationssektioner.

-- 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 som naboskabsliste

Repræsenter en graf som en tabel med tabeller: Hver nøgle er en knude, og dens værdi er en liste over naboer. Denne repræsentation som naboskabsliste er hukommelseseffektiv for tynde grafer og nem at arbejde med i 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

Ændring af indlejrede felter

Ændr indlejrede felter ved at tilgå den overordnede tabel og tildele en værdi til nøglen. Da tabeller videregives som referencer, kan enhver funktion, der modtager en tabel, ændre dens indhold direkte — kaldet ser ændringerne.

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

Serialisering af indlejrede tabeller

Det er nyttigt at konvertere en indlejret tabel til en streng ved fejlfinding eller logning. En simpel rekursiv serializer håndterer enhver dybde, men den kan ikke håndtere cyklusser (cirkulære referencer).

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

Tynde matricer

En todimensionel matrix, der gemmes naivt, spilder hukommelse ved store, tynde input. Gem kun poster, der ikke er nul, i en indlejret tabel: matrix[row][col] = value. Det kan repræsentere enorme matricer effektivt, når de fleste værdier er nul.

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)

Dyb lighedskontrol

Tabeller sammenlignes efter reference med ==, ikke efter værdi. Hvis du vil sammenligne indlejrede tabeller strukturelt, skal du skrive en rekursiv lighedsfunktion, der sammenligner hvert nøgle-værdi-par og kalder sig selv rekursivt for indlejrede tabeller.

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

Hurtigt tjek

Hvad sker der, når du tilgår t.a.b, og t.a er nil?

Opsamling: Indlejrede tabeller

Opsummering:

  • Tabeller kan indlejres vilkårligt: t.a.b.c
  • Beskyt dyb adgang: t and t.a and t.a.b
  • Tabeller er referencetyper — funktioner ændrer dem direkte
  • Array med poster: {{name=...},{name=...}}
  • Tynd matrix: indlejrede tabeller giver effektiv hukommelsesbrug
  • Dyb lighed kræver rekursiv sammenligning
Gratis at komme i gang

Lær Lua med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
40
Lektioner
159

Ofte stillede spørgsmål

Er lektionen “Indlejrede tabeller og strukturerede data” gratis?

Ja — alle 3 lektioner i læringssporet Lua Academy, inklusive “Indlejrede tabeller og strukturerede data”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Lua Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Indlejrede tabeller og strukturerede data”?

Opbyg indlejrede strukturer, og tilgå felter på dybe niveauer. Du øver dig i Lua Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Lua Academy?

Der kræves ingen tidligere erfaring. Lua Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.

Hvor lang tid tager lektionen “Indlejrede tabeller og strukturerede data”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Lua Academy-lektion?

Ja. Alle Lua Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Tabeller som arrays
  2. Tabeller som ordbøger
  3. Iteration gennem tabeller med pairs og ipairs
  4. Indlejrede tabeller og strukturerede data
← Tilbage til Lua Academy