Perl/Variabili hash
Wikibooks, manuali e libri di testo liberi.
Gli array associativi o hash si possono immaginare come dei vettori che hanno i vagoni "con nome" al posto che numerati. Analogamente agli array sono un insieme di scalari.Come nel treno le carrozze sono numerate , così negli hash per identificare una informazione si usa un "nome". Non esiste però alcun modo di legare l'ordine di immissione dei dati e il loro successivo recupero. L'unica garanzia è che ogni "nome" assegnato al un vagone (chiave-key) corrisponde uno ed un unico valore (valore-value).
Indice |
[modifica] Il nome
Come per le scalari i nomi degli hash Per identificare una variabile scalare (un valore) occorre anteporre al nome il carattere $. Il nome di una variabile DEVE iniziare con "lettere", "_" , "'", mentre dal secondo carattere oltre ai precedenti si possono usare i "numeri" fino ad un massimo di 256 caratteri.Inoltre essendo un linguaggio "case sensitive" le lettere maiuscole e le lettere minuscole sono differenti.
%a; # è la variabile a %A; # è la variabile A diversa da a
NOTA: il nome di una variabile non può iniziare con numeri !!!
[modifica] Il contenuto
Il contenuto è un qualsiasi scalare.
A differenza del vettore l'hash è un elemento che associa ad UNA stringa (detta chiave) UN valore. Quindi non è possibile avere più chiavi con lo stesso nome nello stesso hash.
Vediamo la sintassi per creare un hash:
%a; #Ho definito un hash ma non l'ho riempito
%a = (); #Ho definito un hash ed è vuoto !
%a = ( mario => 'maria'
, giancarlo => 'giancarla'
, carmelo => 'carmela'); # ho definito un hash con una array e associazioni "chiare"
%a = ( 'mario' , 'maria' , 'giancarlo' , 'giancarla' , 'carmelo' , 'carmela' ); # ho definito un hash con un vettore
In questo modo ho associato alla chiave mario => il valore maria , alla chiave giancarlo => il valore giancarla e alla chiave carmelo => il valore carmela.
NOTA: Per definire un hash si usa un vettore.Tuttavia mentre un vettore è una "fila" di valori, l'hash è una associazione chiave => valore.
Per ottenere il valore associato ad una chiave si usa questa forma:
print $a{mario}."\n";
che mostrerà "maria". Come si può notare il costrutto $a{<nome>} non è equivoco ed identifica in modo assoluto l'unico valore associato a <nome>. Da notare che i sigilli rimangono coerenti : l'elemento associato a <nome> è uno scalare !!!.
Ricordo nell'hash non è possibile attribuire più di un valore ad una stessa chiave, quindi le chiavi sono univoche dentro uno stesso hash
[modifica] Gestire gli array associativi
Abbiamo detto che gli array associativi usano "key" associate a "value". Vediamo ora come "gestire" queste entità.
Per ottenere l'elenco delle chiavi si usa keys
print (keys %a)."\n";
che torna l'elenco di tutte le chiavi che compongono %a. Da notare che è sicuro che ci siano tutte le chiavi ma l'ordine non è mai assicurato.
Per ottenere i valori si usa values
print (values %a)."\n";
che torna l'elenco di tutti i valori che compongono %a. Da notare che è sicuro che ci siano tutti i valori ma l'ordine non è mai assicurato.
entrambe queste funzioni ritornano un array composto di tutte le informazioni richieste di %a (key o value).
Vediamo ora una istruzione che , ogni volta che viene invocata, ritorna un elemento dell'array associativo:
($key, $value) = each %a;
Vediamo questo esempio:
%contact = ( mario => '0220202020'
, pippo => '0330303030'
, alfa => '0440404040'
);
($key, $value) = each %contact;
print "key:$key ,value:$value\n";
($key, $value) = each %contact;
print "key:$key ,value:$value\n";
($key, $value) = each %contact;
print "key:$key ,value:$value\n";
che scriverà ogni chiave valore presente in %contact. Da notare che è sicuro che ogni volta "each" torni un nuovo valore presente in %contact ma l'ordine non è mai assicurato.
[modifica] exists e delete
Queste due funzioni consentono:
- di verificare se un certo dato esiste
- di poter cancellare un certo dato.
Quindi usando exists è possibile verificare la presenza di una chiave:
%a = ( mario => 'maria'
, giancarlo => 'giancarla'
, carmelo => 'carmela');
print (exists $a{mario})." , ".(exists $a{beppe})."\n";
che mostrerà:
1 , 0
Mentre usando delete , come per gli array, è possibile togliere una corrispondenza chiave => valore :
%a = ( mario => 'maria'
, giancarlo => 'giancarla'
, carmelo => 'carmela');
$b = delete ( $a{mario} );
print "b=$b , %a:".join(" , " ,(keys %a))."\n";
che mostrerà:
b=maria , %a:giancarlo , carmelo
[modifica] Notazione { x , y , z }
Come per i vettori, anche per gli hash esiste una notazione che consente di trattare più informazioni su uno stesso hash.
%lettere = ( a => 'A', b => 'B' , c => 'C' , d => 'D' );
@lettere{ e , f , g } = ( 'E' , 'F' , 'G' );
print "lettere di e :$lettere{e}\n";
che mostrerà:
lettere di e :E
DA NOTARE che, nel secondo assegnamento, il sigillo di lettere è cambiato da % a @ : dato che si tratta di più valori ($lettere{e},$lettere{f},$lettere{g}) è obbligatorio mettere @ e non %. Se ci si riflette un attimo l'array ( 'E' , 'F' , 'G' ) contiene solo i valori e deve corrispondere ad un array.Nel caso ci fosse stato il sigillo % le chiavi devono essere nell'array di destra.
[modifica] Dopo tanta teoria un po' di pratica
Vediamo ora una soluzione ottenibile con le informazioni finora trattate.
ESEMPIO1 Assegnare ad un hash i numeri da 1 a 12 e i corrispondenti mesi.
Soluzione1 - esplicita -
%h = ( 1 => 'gennaio'
, 2 => 'febbraio'
, 3 => 'marzo'
, 4 => 'aprile'
, 5 => 'maggio'
, 6 => 'giugno'
, 7 => 'luglio'
, 8 => 'agosto'
, 9 => 'settembre'
, 10 =>'ottobre'
, 11 =>'novembre'
, 12 =>'dicembre'
);
Soluzione2 - dall'esempio degli array -
@h {1 .. 12} = split ( " " , 'gennaio febbraio marzo aprile maggio giugno luglio agosto settembre ottobre novembre dicembre" );
Soluzione3 - al risparmio -
@h {1 .. 12} = qw( gennaio febbraio marzo aprile maggio giugno luglio agosto settembre ottobre novembre dicembre );
ESEMPIO2 Scrivere il dato corrispondente alla mese 3.
print $h{3}."\n";
nota: il terzo mese ha le informazioni associate alla chiave '3' e non è più importante la posizione come per gli array.
ESEMPIO3 Dato l'array precedente scrivere i dati relativi al mese numero 3 nella seguente forma:"il mese " il numero del mese seguito da "ha il nome :" il relativo nome.
$meseDaScrivere = 3;
print "il mese ". $meseDaScrivere # numero del mese
." ha il nome: ". $h{$meseDaScrivere} # nome del mese
."\n";
[modifica] Riassunto
Gli hash:
- sono identificati dal sigillo "%" davanti al nome
- contengono valori scalari associati a chiavi (stringhe)
- si ottengono/assegnano i dati (scalari) utilizzando la sintassi $'nome'{'posizione'}
- si utilizzano le funzioni keys , values avere l'elenco degli elementi
- si utilizza la funzione exists per sapere se c'è una chiave.