I dizionari in sono strutture dati che memorizzano coppie chiave-valore, simili a un'enciclopedia dove ad ogni termine (chiave) corrisponde una definizione (valore). A differenza degli array, non si basano su indici numerici ordinati ma su etichette uniche, rendendo il recupero delle informazioni rapido e intuitivo.
Nei videogiochi sono essenziali per gestire sistemi complessi: si usano per creare un inventario, salvare le statistiche dei personaggi (come la salute o la forza) o definire le configurazioni dei livelli.
Vantaggi di un dizionario rispetto ad un array
Lo svantaggio principale di un array è che i dati possono essere memorizzati in qualsiasi ordine, rendendo difficile trovare e recuperare dati specifici. Un dizionario supera questo svantaggio utilizzando le chiavi. Anche i dizionari memorizzano i dati in qualsiasi ordine, ma ciascun dato è una coppia chiave-valore: la chiave è un modo di identificare un dato così da poterlo recuperare, il valore è il dato vero e proprio che si desidera memorizzare. Ad esempio, un dizionario usato per memorizzare le statistiche di un giocatore potrebbe avere una chiave "forza" (una stringa che funge da etichetta mnemonica) a cui corrisponde il numero intero 10 (il valore associato alla chiave).
Poiché è sempre possibile recuperare i dati utilizzando una chiave, il fatto che un dizionario non sia ordinato non ha importanza. I dizionari sono utili per recuperare rapidamente i dati, cosa che non è così semplice con gli array: due array possono contenere gli stessi dati, ma l'indice utilizzato per recuperare dati identici può differire notevolmente. Invece l'ordine in cui si memorizzano i dati in un dizionario non ha importanza: se si conosce la chiave associata ai dati che si desidera recuperare, è sempre possibile recuperare tali dati.
Creare un dizionario
Per creare un dizionario bisogna definire tre parti:
- il nome del dizionario;
- una coppia di parentesi graffe {} che includono le coppie chiave-valore;
- una o più coppie di dati chiave-valore separate da due punti : mentre le varie coppie chiae-valore sono separate l'una dall'altra da una virgola ,.
NOTA BENE: le chiavi in un dizionario devono essere uniche (cioè non possono esistere 2 o più chiavi uguali), mentre ovviamente alcuni tra i valori possono coincidere. L'unicità delle chiavi è necessaria per recuperare il valore corretto associato a ciascun dato.
La sintassi è la seguente:
<chiave_2> : valore_2,
...
<chiave_n> : valore_n,
In GDScript, i dizionari sono estremamente flessibili. A differenza di altri linguaggi, le chiavi possono essere di quasi tutti i tipi di dati integrati, purché siano valori validi. Quindi le chiavi possono essere di tipi primitivi:
- stringhe (String), sono le più frequenti, ideali per etichette leggibili come "salute" o "forza";
- numeri interi (int), utiili per mappare ID numerici (ad esempio 101: "Spada di Fuoco").
- numeri decimali (float), sono possibili ma sconsigliati a causa di potenziali errori di precisione decimale;
- valori booleani (bool), si possono usare true o false come chiavi, ma sono usati raramente.
ESEMPIO: un dizionario con chiavi definite da tipi primitivi (da notare la chiave booleana false al cui valore è stato associato il booleano true!).
OUTPUT dell'esecuzione (estendi l'area di testo se necessario):
Le chiavi possono essere anche di tipi complessi, per esempio una chiave può a sua volta essere un altro dizionario, un array, o un tipo di risorse integrato nel motore di Godot (vettori, risorse, nodi, oggetti).
Accesso, modifica e aggiunta di elementi
Una volta che il dizionario è stato creato, il passo successivo è accedere ai dati che in esso registrati. Per farlo si usa il nome del dizionario seguito dalla chiave (racchiusa tra parentesi quadre) a cui i dati sono collegati, con la sintassi:
ESEMPIO
var personaggio = {"Nome": "Paperino", "Fortuna": 3}
print("Nome: ", personaggio["Nome"])
print("Livello di fortuna: ", personaggio["Fortuna"])
OUTPUT dell'esecuzione (estendi l'area di testo se necessario):
Per modificare un elemento (il valore associato ad una chiave) o aggiungerne uno nuovo (una nuova chiave ed il relativo valore associato), si usa la stessa sintassi in combinazione con l'operatore di assegnamento =; se la chiave esiste, il nuovo valore sovrascrive il vecchio, altrimenti viene aggiunta una nuova chiave. La sintassi è:
ESEMPIO
var personaggio = {"Nome": "Paperino", "Fortuna": 3}
print("Nome: ", personaggio["Nome"])
print("Livello di fortuna: ", personaggio["Fortuna"])
print("Modifica la fortuna da 3 a 1")
personaggio["Fortuna"] = 1
print("Livello di fortuna: ", personaggio["Fortuna"])
print("Aggiunta di una nuova chiave")
personaggio["Destrezza"] = 5
print("Personaggio = ", personaggio)
OUTPUT dell'esecuzione (estendi l'area di testo se necessario):
Un metodo alternativo per leggere il valore di una chiave è usare il metodo get(<chiave>); se la chiave non esiste viene restituito un valore predefinito (per esempio null).
A partire da Godot 4.3 è stato aggiunto il metodo
get_or_add(<chiave>, val_predefinito_opzionale) che restituisce il valore della chiave se essa esiste nel dizionario, altrimenti la aggiunge automaticamente con un valore predefinito e restituisce tale valore.
NOTA BENE: il valore predefinito è opzionale; se la chiave non esiste ed il valore predefinito è omesso, la chiave è aggiunta con valore null, altrimenti la chiave viene aggiunta con il valore passato alla funzione get_or_add().
ESEMPIO:
var personaggio = {"Nome": "Topolino", "Intelligenza": 10}
print("Personaggio = ", personaggio)
print("Nome: ", personaggio.get("Nome")) # "Topolino"
print("Destrezza: ", personaggio.get("Destrezza")) # null
print("Destrezza: ", personaggio.get_or_add("Destrezza", 10)) # 10
print("Personaggio = ", personaggio)
print("Fortuna: ", personaggio.get_or_add("Fortuna")) # null
print("Personaggio = ", personaggio)
OUTPUT dell'esecuzione (estendi l'area di testo se necessario):
Rimozione di elementi
Per eliminare una chiave dal dizionario, si usa il metodo erase(<chiave>);
NOTA BENE: è assolutamente sconsigliato eliminare chiavi mentre si sta iterando su un dizionario (per esempio con un ciclo for); tale operazione va eseguita iterando sull'array ritornato dal metodo keys() (si veda la prossima sezione).
ESEMPIO:
var personaggio = {
"Nome": "Topolino",
"Intelligenza": 10,
"Fortuna": 5
}
print("Personaggio = ", personaggio)
print("Elimino la fortuna")
personaggio.erase("Fortuna")
print("Personaggio = ", personaggio)
OUTPUT dell'esecuzione (estendi l'area di testo se necessario):
Metodi di base per i dizionari
I metodi base dei dizionari ricalcano quelli già viste per enumerazioni ed array, eccone una carrellata:
- size(), restituisce il numero di "entrate" (in pratica il numero di chiavi) del dizionario;
- keys(), restituisce un array contenente le chiavi del dizionario;
- values(), restituisce un array dei valori associati alle chiavi;
- duplicate(<valore_booleano>), esegue una copia del dizionario in modo analogo a quanto visto per gli array, ossia d.duplicate(false) esegue una copia superficiale (shallow copy) del dizionario d, mentre d.duplicate(true) esegue una copia profonda (deep copy) del dizionario d (come per gli array, vengono duplicati ricorsivamente eventuali array o altri dizionari in esso annidati ma non risorse più complesse);
- clear(), svuota il dizionario, ossia elimina tutte le chiavi ed i valori in esso contenuti;
- is_empty(), restituisce il valore booleano true se il dizionario è vuoto (ossia se è {}), false altrimenti;
ESEMPIO: uso dei metodi di base nei dizionari
OUTPUT dell'esecuzione (estendi l'area di testo se necessario):
Altri metodi utili per le chiavi
Per le chiavi esistono metodi di utilità che servono a verificarne l'esistenza o a trovare una chiave se il suo valore è noto. Esiste inoltre un metodo alternativo per aggiungere una nuova chiave o modificarne una esistente:
- has(<key>), restituisce true se il dizionario contiene la chiave <key>, false altrimenti;
- find_key(<val>), restituisce la prima chiave a cui è associato il valore <val>. Se ci sono più chiavi con lo stesso valore restituisce solo la prima trovata. Per trovare tutte le chiavi con lo stesso valore è necessario iterare sul dizionario con un ciclo;
- set(<key>, <val>), imposta la chiave <key> al valore <val> e restituisce il valore booleano true se il valore è stato impostato correttamente (se la chiave non esiste viene aggiunta automaticamente); restituisce false se non è stato possibile eseguire l'impostazione (ad esempio quando il tipo del valore non coincide con ciò che dovrebbe essere, oppure se il dizionario è a sola lettura).
ESEMPIO: verifica dell'esistenza di chiavi in un dizionario e confronto del valore associato a chiavi di tipo diverso. Da notare nel codice l'uso della funzione is_same() che evita un errore runtime quando si confronta il valore associato alla chiave "Nome" (la stringa "Topolino") con il valore intero k.
OUTPUT dell'esecuzione (estendi l'area di testo se necessario):
Per ulteriori informazioni sui dizionari consultare la documentazione ufficiale: https://docs.godotengine.org/en/stable/classes/class_dictionary.html
| Precedente | Indice | Successivo |