Dizionari e Record in Lua
In Lua, le tabelle non sono solo array numerici: possono funzionare come dizionari (array associativi), dove ogni valore e associato a una chiave arbitraria. Questa caratteristica rende le tabelle lo strumento universale per strutturare dati in Lua. In questa guida vedremo come usare le tabelle come dizionari e record.
Tabelle come Dizionari
Un dizionario (o mappa) associa chiavi a valori. In Lua, le chiavi possono essere di qualsiasi tipo (stringhe, numeri, booleani), ad eccezione di nil.
-- Creare un dizionario
local capitali = {
["Italia"] = "Roma",
["Francia"] = "Parigi",
["Germania"] = "Berlino",
["Spagna"] = "Madrid"
}
print(capitali["Italia"]) --> Roma
print(capitali["Francia"]) --> Parigi
Le parentesi quadre permettono di usare qualsiasi espressione come chiave, incluse stringhe con spazi o caratteri speciali.
Notazione Punto vs Parentesi Quadre
Quando le chiavi sono stringhe valide come identificatori Lua (senza spazi, iniziano con lettera o underscore), si puo usare la notazione punto, che risulta piu leggibile.
local persona = {
nome = "Marco",
eta = 30,
citta = "Milano"
}
-- Notazione punto (equivalente a persona["nome"])
print(persona.nome) --> Marco
print(persona.eta) --> 30
-- Notazione parentesi quadre (necessaria per chiavi dinamiche)
local campo = "citta"
print(persona[campo]) --> Milano
-- Chiavi con spazi richiedono le parentesi quadre
local dati = {
["nome completo"] = "Marco Rossi"
}
print(dati["nome completo"]) --> Marco Rossi
La notazione punto e semplicemente uno zucchero sintattico: t.chiave e identico a t["chiave"].
Uso come Record
Le tabelle in Lua sono perfette per rappresentare record o strutture dati con campi nominati, simili a struct o oggetti in altri linguaggi.
-- Record di uno studente
local studente = {
nome = "Giulia",
cognome = "Bianchi",
matricola = 12345,
voti = {28, 30, 25, 27, 30}
}
print(studente.nome .. " " .. studente.cognome) --> Giulia Bianchi
print("Matricola: " .. studente.matricola) --> Matricola: 12345
-- Calcolare la media dei voti
local somma = 0
for _, voto in ipairs(studente.voti) do
somma = somma + voto
end
local media = somma / #studente.voti
print("Media: " .. media) --> Media: 28.0
Aggiungere e Modificare Coppie Chiave-Valore
Per aggiungere una nuova coppia o modificare un valore esistente, basta assegnare un valore alla chiave desiderata.
local config = {
lingua = "it",
tema = "scuro"
}
-- Aggiungere una nuova chiave
config.versione = "2.0"
config["max_tentativi"] = 3
-- Modificare un valore esistente
config.tema = "chiaro"
print(config.tema) --> chiaro
print(config.versione) --> 2.0
print(config["max_tentativi"]) --> 3
Eliminare una Chiave
Per eliminare una coppia chiave-valore da un dizionario, si assegna nil alla chiave.
local frutta = {
mela = 5,
banana = 3,
arancia = 8
}
-- Eliminare la chiave "banana"
frutta.banana = nil
-- Verificare che sia stata eliminata
print(frutta.banana) --> nil
Verificare l’Esistenza di una Chiave
Poiche accedere a una chiave inesistente restituisce nil, si puo verificare l’esistenza di una chiave controllando se il valore e diverso da nil.
local utenti = {
admin = true,
editor = true,
viewer = true
}
if utenti.admin then
print("L'utente admin esiste")
end
if utenti.superadmin == nil then
print("L'utente superadmin non esiste")
end
-- Attenzione: se il valore e false, non e la stessa cosa di nil
local impostazioni = {
attivo = false,
visibile = true
}
if impostazioni.attivo ~= nil then
print("La chiave 'attivo' esiste (valore: " .. tostring(impostazioni.attivo) .. ")")
end
Iterare con pairs()
La funzione pairs() permette di iterare su tutte le coppie chiave-valore di un dizionario. L’ordine di iterazione non e garantito.
local traduzione = {
ciao = "hello",
mondo = "world",
gatto = "cat",
casa = "house"
}
for chiave, valore in pairs(traduzione) do
print(chiave .. " -> " .. valore)
end
-- Output (ordine non garantito):
-- ciao -> hello
-- gatto -> cat
-- mondo -> world
-- casa -> house
Nota importante: pairs() itera in ordine arbitrario. Se serve un ordine specifico, bisogna ordinare le chiavi separatamente.
Contare gli Elementi di un Dizionario
L’operatore # non funziona per contare le coppie chiave-valore di un dizionario. Bisogna contare manualmente.
local dati = {
a = 1,
b = 2,
c = 3
}
-- L'operatore # non funziona qui
print(#dati) --> 0 (non conta le chiavi stringa)
-- Contare manualmente
local conteggio = 0
for _ in pairs(dati) do
conteggio = conteggio + 1
end
print("Numero di coppie: " .. conteggio) --> Numero di coppie: 3
Dizionari Annidati
I dizionari possono contenere altri dizionari come valori, permettendo di creare strutture dati complesse.
local azienda = {
nome = "TechCorp",
sede = {
citta = "Roma",
via = "Via del Corso 100",
cap = "00186"
},
dipendenti = {
{nome = "Anna", ruolo = "sviluppatore"},
{nome = "Luca", ruolo = "designer"},
{nome = "Sara", ruolo = "project manager"}
}
}
print(azienda.nome) --> TechCorp
print(azienda.sede.citta) --> Roma
print(azienda.dipendenti[1].nome) --> Anna
-- Iterare sui dipendenti
for i, dip in ipairs(azienda.dipendenti) do
print(i .. ". " .. dip.nome .. " - " .. dip.ruolo)
end
Esempio Pratico: Rubrica Telefonica
local rubrica = {}
-- Funzione per aggiungere un contatto
local function aggiungi_contatto(nome, telefono, email)
rubrica[nome] = {
telefono = telefono,
email = email
}
print("Contatto aggiunto: " .. nome)
end
-- Funzione per cercare un contatto
local function cerca_contatto(nome)
local contatto = rubrica[nome]
if contatto then
print("Nome: " .. nome)
print("Telefono: " .. contatto.telefono)
print("Email: " .. contatto.email)
else
print("Contatto '" .. nome .. "' non trovato")
end
end
-- Funzione per elencare tutti i contatti
local function elenca_tutti()
print("--- Rubrica ---")
for nome, info in pairs(rubrica) do
print(nome .. ": " .. info.telefono .. " | " .. info.email)
end
end
aggiungi_contatto("Marco", "333-1234567", "marco@email.com")
aggiungi_contatto("Giulia", "328-7654321", "giulia@email.com")
aggiungi_contatto("Paolo", "340-1112233", "paolo@email.com")
elenca_tutti()
cerca_contatto("Giulia")
cerca_contatto("Andrea")
Conclusioni
Le tabelle Lua usate come dizionari offrono un modo flessibile e potente per associare chiavi a valori. La notazione punto semplifica l’accesso ai campi stringa, mentre le parentesi quadre permettono di gestire chiavi dinamiche o non convenzionali. Comprendere la differenza tra pairs() e ipairs(), sapere come verificare l’esistenza delle chiavi e come eliminare coppie chiave-valore e essenziale per lavorare efficacemente con i dati strutturati in Lua.