Successivo: , Precedente: , Su: Funzioni di libreria   [Contenuti][Indice]


10.7 Attraversare vettori di vettori

Vettori di vettori trattava di come gawk mette a disposizione vettori di vettori. In particolare, qualsiasi elemento di un vettore può essere uno scalare o un altro vettore. La funzione isarray() (vedi la sezione Funzioni per conoscere il tipo di una variabile) permette di distinguere un vettore da uno scalare. La seguente funzione, walk_array(), attraversa ricorsivamente un vettore, stampando gli indici e i valori di ogni elemento. Viene chiamata col vettore e con una stringa che contiene il nome del vettore:

function walk_array(vett, nome,      i)
{
    for (i in vett) {
        if (isarray(vett[i]))
            walk_array(vett[i], (nome "[" i "]"))
        else
            printf("%s[%s] = %s\n", nome, i, vett[i])
    }
}

Funziona eseguendo un ciclo su ogni elemento del vettore. Se un dato elemento è esso stesso un vettore, la funzione chiama sé stessa ricorsivamente, passando il sottovettore e una nuova stringa che rappresenta l’indice corrente. In caso contrario, la funzione stampa semplicemente il nome, l’indice e il valore dell’elemento. Qui di seguito si riporta un programma principale che ne mostra l’uso:

BEGIN {
    a[1] = 1
    a[2][1] = 21
    a[2][2] = 22
    a[3] = 3
    a[4][1][1] = 411
    a[4][2] = 42

    walk_array(a, "a")
}

Quando viene eseguito, il programma produce il seguente output:

$ gawk -f walk_array.awk
-| a[1] = 1
-| a[2][1] = 21
-| a[2][2] = 22
-| a[3] = 3
-| a[4][1][1] = 411
-| a[4][2] = 42

La funzione appena illustrata stampa semplicemente il nome e il valore di ogni elemento costituito da un vettore scalare. Comunque è facile generalizzarla, passandole il nome di una funzione da chiamare quando si attraversa un vettore. La funzione modificata è simile a questa:

function process_array(vett, nome, elab, do_arrays,   i, nuovo_nome)
{
    for (i in vett) {
        nuovo_nome = (nome "[" i "]")
        if (isarray(vett[i])) {
            if (do_arrays)
                @elab(nuovo_nome, vett[i])
            process_array(vett[i], nuovo_nome, elab, do_arrays)
        } else
            @elab(nuovo_nome, vett[i])
    }
}

Gli argomenti sono i seguenti:

vett

Il vettore.

nome

Il nome del vettore (una stringa).

elab

Il nome della funzione da chiamare.

do_arrays

Se vale vero, la funzione può gestire elementi che sono sottovettori.

Se devono essere elaborati sottovettori, questo vien fatto prima di attraversarne altri.

Quando viene eseguita con la seguente struttura, la funzione produce lo stesso risultato della precedente versione di walk_array():

BEGIN {
    a[1] = 1
    a[2][1] = 21
    a[2][2] = 22
    a[3] = 3
    a[4][1][1] = 411
    a[4][2] = 42

    process_array(a, "a", "do_print", 0)
}

function do_print(nome, elemento)
{
    printf "%s = %s\n", nome, elemento
}

Successivo: , Precedente: , Su: Funzioni di libreria   [Contenuti][Indice]