0Pricing
Lua Academy · Lezione

Tabelle annidate e dati strutturati

Costruisca strutture annidate e acceda ai campi profondi.

Tabelle annidate e dati strutturati è una lezione Lua Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Lua Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Lua Academy include 4 lezioni in totale.

Nozioni di base sulle tabelle annidate

Le tabelle possono contenere altre tabelle come valori, creando strutture di profondità arbitraria. Acceda ai campi annidati concatenando la notazione con il punto o con le parentesi quadre. Le tabelle intermedie mancanti causano errori: verifichi sempre che le tabelle contenitore esistano prima di accedere ai campi profondi.

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

Accesso sicuro ai campi profondi

Accedere a un campo di un valore nil causa l'errore "attempt to index a nil value". Lo eviti usando la valutazione short-circuit di and: t and t.a and t.a.b. In alcuni codebase viene definito un helper get(t, ...) che attraversa in sicurezza una catena di chiavi.

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 di record

Un pattern comune è un array di tabelle (record). Ogni elemento è una tabella con campi denominati. Iteri con ipairs e acceda ai campi tramite il nome. Questo è l'equivalente Lua di un array di oggetti o di un elenco di struct.

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

Creazione dinamica di tabelle annidate

Costruisca le strutture annidate progressivamente, creando le tabelle interne quando necessario. Inizializzi sempre una tabella prima di inserirvi elementi. Un errore comune consiste nel dimenticare di creare prima la tabella interna e tentare poi di indicizzare 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

Tabella come configurazione simile a JSON

Le tabelle Lua vengono spesso usate per i file di configurazione, in modo simile a JSON o YAML. Il file restituisce una tabella e l'applicazione la carica con dofile() o require(). Le tabelle annidate rappresentano sezioni di configurazione annidate.

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

Grafo come lista di adiacenza

Rappresenti un grafo come una tabella di tabelle: ogni chiave è un nodo e il valore associato è un elenco dei nodi adiacenti. Questa rappresentazione tramite lista di adiacenza è efficiente in termini di memoria per i grafi sparsi ed è facile da usare in 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

Modifica dei campi annidati

Modifichi i campi annidati accedendo alla tabella contenitore e assegnando un valore alla chiave. Poiché le tabelle vengono passate per riferimento, qualsiasi funzione che riceva una tabella può modificarne direttamente il contenuto: il chiamante vede le modifiche.

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

Serializzazione di tabelle annidate

Convertire una tabella annidata in una stringa è utile per il debug o la registrazione. Un semplice serializzatore ricorsivo gestisce qualsiasi profondità, ma non gestisce i cicli (riferimenti circolari).

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

Matrici sparse

Memorizzare ingenuamente una matrice 2D spreca memoria per input grandi e sparsi. Memorizzi solo le voci diverse da zero in una tabella annidata: matrix[row][col] = value. Ciò consente di rappresentare in modo efficiente matrici enormi quando la maggior parte dei valori è 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)

Controllo dell'uguaglianza profonda

Le tabelle vengono confrontate per riferimento con ==, non per valore. Per confrontare strutturalmente tabelle annidate, scriva una funzione ricorsiva di uguaglianza che confronti ogni coppia chiave-valore e richiami sé stessa sulle tabelle annidate.

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

Verifica rapida

Che cosa accade quando si accede a t.a.b e t.a è nil?

Riepilogo: tabelle annidate

Riepilogo:

  • Le tabelle possono essere annidate a qualsiasi profondità: t.a.b.c
  • Proteggere l'accesso ai campi profondi: t and t.a and t.a.b
  • Le tabelle sono tipi riferimento: le funzioni le modificano direttamente
  • Array di record: {{name=...},{name=...}}
  • Matrice sparsa: tabelle annidate per una maggiore efficienza della memoria
  • L'uguaglianza profonda richiede un confronto ricorsivo

Domande Frequenti

La lezione «Tabelle annidate e dati strutturati» è gratuita?

Sì — il testo completo di «Tabelle annidate e dati strutturati» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Lua Academy, passa a CoddyKit PRO. Il corso Lua Academy include 4 lezioni in totale.

Cosa imparerò in «Tabelle annidate e dati strutturati»?

Costruisca strutture annidate e acceda ai campi profondi. Eserciti Lua Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Lua Academy?

Non è richiesta alcuna esperienza precedente. Lua Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Tabelle annidate e dati strutturati»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Lua Academy?

Sì. Ogni lezione Lua Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Tabelle come array
  2. Tabelle come dizionari
  3. Iterazione delle tabelle con pairs e ipairs
  4. Tabelle annidate e dati strutturati
← Torna a Lua Academy