Successivo: Sommario dei vettori, Precedente: Vettori multidimensionali, Su: Vettori [Contenuti][Indice]
gawk
migliora l’accesso ai vettori multidimensionali di
awk
standard e mette a disposizione dei veri vettori di vettori.
Agli elementi di un sottovettore si fa riferimento tramite il loro indice
racchiuso tra parentesi quadre, proprio come gli elementi del vettore
principale. Per esempio, quel che segue crea un sottovettore con due elementi
all’indice 1
del vettore principale a
:
a[1][1] = 1 a[1][2] = 2
Questo simula un vero vettore bidimensionale. Ogni elemento di un sottovettore
può contenere un altro sottovettore come valore, che a sua volta può
contenere anche ulteriori vettori. In questo modo, si possono creare vettori
di tre o più dimensioni.
Gli indici possono essere costituiti da qualunque espressione di
awk
, compresi dei
valori scalari separati da virgole (cioè, un indice multidimensionale simulato
di awk
). Quindi, la seguente espressione è valida in
gawk
:
a[1][3][1, "nome"] = "barney"
Ogni sottovettore e il vettore principale possono essere di diversa lunghezza.
Di fatto, gli elementi di un vettore o un suo sottovettore non devono essere
necessariamente tutti dello stesso tipo. Ciò significa che il vettore
principale come anche uno qualsiasi dei suoi sottovettori può essere
non rettangolare,
o avere una struttura frastagliata. Si può assegnare un valore scalare
all’indice 4
del vettore principale a
, anche se a[1]
è esso stesso un vettore e non uno scalare:
a[4] = "Un elemento in un vettore frastagliato"
I termini dimensione, riga e colonna sono privi di
significato quando sono applicati
a questo tipo di vettore, ma d’ora in poi useremo “dimensione” per indicare
il numero massimo di indici necessario per far riferimento a un elemento
esistente. Il tipo di ogni elemento che è già stato assegnato non può essere
cambiato assegnando un valore di tipo diverso. Prima si deve eliminare
l’elemento corrente, per togliere completamente dalla memoria di
gawk
ogni riferimento a quell’indice:
delete a[4] a[4][5][6][7] = "Un elemento in un vettore quadridimensionale"
Le due istruzioni rimuovono il valore scalare dall’indice 4
e
inseriscono poi un
sottovettore interno a tre indici contenente uno scalare. Si può anche
eliminare un intero sottovettore o un sottovettore di sottovettori:
delete a[4][5] a[4][5] = "Un elemento nel sottovettore a[4]"
Si deve però ricordare che non è consentito eliminare il vettore principale
a
e poi usarlo come scalare.
Le funzioni predefinite che accettano come argomenti dei vettori possono
essere usate
anche con i sottovettori. Per esempio, il seguente frammento di codice usa
length()
(vedi la sezione Funzioni di manipolazione di stringhe)
per determinare il numero di elementi nel vettore principale a
e nei suoi sottovettori:
print length(a), length(a[1]), length(a[1][3])
Il risultato per il nostro vettore principale a
è il seguente:
2, 3, 1
L’espressione ‘indice in vettore’
(vedi la sezione Come esaminare un elemento di un vettore) funziona allo stesso modo sia per
i vettori regolari in stile awk
che per i vettori di vettori. Per esempio, le espressioni ‘1 in a’,
‘3 in a[1]’ e ‘(1, "nome") in a[1][3]’ risultano tutte di valore
uno (vero) per il nostro vettore a
.
L’istruzione ‘for (elemento in vettore)’ (vedi la sezione Visitare tutti gli elementi di un vettore) può essere nidificata per visitare tutti gli elementi di un vettore di vettori che abbia una struttura rettangolare. Per stampare il contenuto (valori scalari) di un vettore di vettori bidimensionale (cioè nel quale ogni elemento di primo livello è esso stesso un vettore, non necessariamente di lunghezza uguale agli altri) si può usare il seguente codice:
for (i in vettore) for (j in vettore[i]) print vettore[i][j]
La funzione isarray()
(vedi la sezione Funzioni per conoscere il tipo di una variabile)
permette di verificare se un elemento di un vettore è esso stesso un vettore:
for (i in vettore) { if (isarray(vettore[i])) { for (j in vettore[i]) { print vettore[i][j] } } else print vettore[i] }
Se la struttura di un vettore di vettori frastagliato è nota in anticipo,
si può spesso trovare il modo per visitarlo usando istruzioni di controllo.
Per esempio,
il seguente codice stampa gli elementi del nostro vettore principale a
:
for (i in a) { for (j in a[i]) { if (j == 3) { for (k in a[i][j]) print a[i][j][k]
} else print a[i][j] } }
Vedi la sezione Attraversare vettori di vettori per una funzione definita dall’utente che “visita” un vettore di vettori di dimensioni arbitrarie.
Si ricordi che un riferimento a un elemento di un vettore non
inizializzato genera un elemento con valore uguale a ""
, la stringa
nulla. Questo ha
un’importante implicazione quando s’intende usare un sottovettore come
argomento di una funzione, come illustrato nel seguente esempio:
$ gawk 'BEGIN { split("a b c d", b[1]); print b[1][1] }' error→ gawk: riga com.:1: fatale: split: secondo argomento error→ non-vettoriale
Il modo per aggirare quest’ostacolo è quello di definire prima b[1]
come vettore creando un indice arbitrario:
$ gawk 'BEGIN { b[1][1] = ""; split("a b c d", b[1]); print b[1][1] }' -| a
Successivo: Sommario dei vettori, Precedente: Vettori multidimensionali, Su: Vettori [Contenuti][Indice]