Array e Liste in Lua
In Lua, non esistono array come tipo di dato dedicato: gli array sono semplicemente tabelle (table) che utilizzano chiavi intere consecutive a partire da 1. Questa convenzione rende le tabelle uno strumento potente e flessibile per gestire collezioni ordinate di dati. In questa guida esploreremo come creare, manipolare e iterare sugli array in Lua.
Creare un Array
Per creare un array in Lua si utilizza il costruttore di tabelle {}. Gli elementi vengono inseriti in ordine e ricevono automaticamente indici interi a partire da 1.
-- Array vuoto
local frutti = {}
-- Array con valori iniziali
local numeri = {10, 20, 30, 40, 50}
-- Array di stringhe
local colori = {"rosso", "verde", "blu", "giallo"}
A differenza di molti altri linguaggi, in Lua gli indici partono da 1, non da 0. Questo e un aspetto fondamentale da ricordare.
Accesso agli Elementi
Per accedere a un elemento dell’array si utilizza la notazione con parentesi quadre [] specificando l’indice.
local animali = {"gatto", "cane", "coniglio", "tartaruga"}
print(animali[1]) --> gatto
print(animali[3]) --> coniglio
print(animali[5]) --> nil (l'elemento non esiste)
-- Modificare un elemento
animali[2] = "pappagallo"
print(animali[2]) --> pappagallo
Accedere a un indice che non esiste restituisce nil, senza generare errori.
Lunghezza di un Array
L’operatore # restituisce la lunghezza di un array, ovvero il numero di elementi con indici interi consecutivi a partire da 1.
local numeri = {10, 20, 30, 40}
print(#numeri) --> 4
local vuoto = {}
print(#vuoto) --> 0
Attenzione: l’operatore # potrebbe dare risultati inattesi se l’array contiene “buchi” (valori nil intermedi). E buona pratica mantenere sempre array senza interruzioni.
Aggiungere Elementi
La funzione table.insert permette di aggiungere elementi all’array. Senza specificare una posizione, l’elemento viene aggiunto in coda.
local lista = {"a", "b", "c"}
-- Aggiungere in coda
table.insert(lista, "d")
print(lista[4]) --> d
-- Aggiungere in una posizione specifica
table.insert(lista, 2, "x")
-- lista ora e: {"a", "x", "b", "c", "d"}
print(lista[2]) --> x
print(lista[3]) --> b
Si puo anche aggiungere un elemento semplicemente assegnandolo alla posizione successiva:
local numeri = {1, 2, 3}
numeri[#numeri + 1] = 4 -- equivale a table.insert(numeri, 4)
Rimuovere Elementi
La funzione table.remove rimuove un elemento dall’array e sposta gli elementi successivi per colmare il vuoto.
local lettere = {"a", "b", "c", "d", "e"}
-- Rimuovere l'ultimo elemento
local ultimo = table.remove(lettere)
print(ultimo) --> e
print(#lettere) --> 4
-- Rimuovere un elemento in una posizione specifica
local rimosso = table.remove(lettere, 2)
print(rimosso) --> b
-- lettere ora e: {"a", "c", "d"}
Iterare su un Array con ipairs
La funzione ipairs e il modo idiomatico per iterare su un array in ordine. Restituisce coppie indice-valore partendo dall’indice 1 e fermandosi al primo nil.
local linguaggi = {"Lua", "Python", "JavaScript", "Go"}
for indice, valore in ipairs(linguaggi) do
print(indice .. ": " .. valore)
end
-- Output:
-- 1: Lua
-- 2: Python
-- 3: JavaScript
-- 4: Go
E possibile anche usare un classico ciclo for numerico:
for i = 1, #linguaggi do
print(i .. ": " .. linguaggi[i])
end
Array Multidimensionali
In Lua, un array multidimensionale e semplicemente un array di array (tabelle annidate).
-- Matrice 3x3
local matrice = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
}
-- Accesso: matrice[riga][colonna]
print(matrice[1][1]) --> 1
print(matrice[2][3]) --> 6
print(matrice[3][2]) --> 8
-- Iterare sulla matrice
for i = 1, #matrice do
for j = 1, #matrice[i] do
io.write(matrice[i][j] .. " ")
end
print() -- nuova riga
end
-- Output:
-- 1 2 3
-- 4 5 6
-- 7 8 9
Pattern Stack (Pila)
Un array puo essere usato come stack (LIFO: Last In, First Out) usando table.insert e table.remove in coda.
local stack = {}
-- Push: aggiungere in cima
table.insert(stack, "primo")
table.insert(stack, "secondo")
table.insert(stack, "terzo")
-- Pop: rimuovere dalla cima
print(table.remove(stack)) --> terzo
print(table.remove(stack)) --> secondo
print(table.remove(stack)) --> primo
Pattern Coda (Queue)
Per una coda (FIFO: First In, First Out), si inserisce in coda e si rimuove dalla testa.
local coda = {}
-- Enqueue: aggiungere in coda
table.insert(coda, "cliente_1")
table.insert(coda, "cliente_2")
table.insert(coda, "cliente_3")
-- Dequeue: rimuovere dalla testa
print(table.remove(coda, 1)) --> cliente_1
print(table.remove(coda, 1)) --> cliente_2
print(table.remove(coda, 1)) --> cliente_3
Nota: rimuovere dalla testa con table.remove(t, 1) ha complessita O(n) perche tutti gli elementi vengono spostati. Per code ad alte prestazioni, si puo usare un approccio con due indici.
Esempio Pratico: Gestione di un Inventario
local inventario = {}
-- Funzione per aggiungere un oggetto
local function aggiungi(oggetto)
table.insert(inventario, oggetto)
print("Aggiunto: " .. oggetto)
end
-- Funzione per rimuovere un oggetto per nome
local function rimuovi(nome)
for i, oggetto in ipairs(inventario) do
if oggetto == nome then
table.remove(inventario, i)
print("Rimosso: " .. nome)
return true
end
end
print("Non trovato: " .. nome)
return false
end
-- Funzione per mostrare l'inventario
local function mostra()
print("--- Inventario ---")
if #inventario == 0 then
print(" (vuoto)")
else
for i, oggetto in ipairs(inventario) do
print(" " .. i .. ". " .. oggetto)
end
end
end
aggiungi("spada")
aggiungi("scudo")
aggiungi("pozione")
mostra()
rimuovi("scudo")
mostra()
Conclusioni
Gli array in Lua sono implementati tramite tabelle con chiavi intere a partire da 1. Grazie alle funzioni table.insert, table.remove e all’iteratore ipairs, e possibile gestire collezioni ordinate di dati in modo semplice e efficace. Ricordare che gli indici partono da 1 e che l’operatore # misura la lunghezza dell’array e fondamentale per scrivere codice Lua corretto e leggibile.