00
:
00
:
00
:
00
•Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

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.