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:

  1. di verificare se un certo dato esiste
  2. 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:

  1. sono identificati dal sigillo "%" davanti al nome
  2. contengono valori scalari associati a chiavi (stringhe)
  3. si ottengono/assegnano i dati (scalari) utilizzando la sintassi $'nome'{'posizione'}
  4. si utilizzano le funzioni keys , values avere l'elenco degli elementi
  5. si utilizza la funzione exists per sapere se c'è una chiave.

Strumenti personali