Successivo: , Precedente: , Su: Fondamenti sui vettori   [Contenuti][Indice]


8.1.5 Visitare tutti gli elementi di un vettore

Nei programmi che usano vettori, è spesso necessario usare un ciclo che esegue un’azione su ciascun elemento di un vettore. In altri linguaggi, dove i vettori sono contigui e gli indici sono limitati ai numeri interi non negativi, questo è facile: tutti gli indici validi possono essere visitati partendo dall’indice più basso e arrivando a quello più alto. Questa tecnica non è applicabile in awk, perché qualsiasi numero o stringa può fare da indice in un vettore. Perciò awk ha un tipo speciale di istruzione for per visitare un vettore:

for (variabile in vettore)
    corpo

Questo ciclo esegue corpo una volta per ogni indice in vettore che il programma ha usato precedentemente, con la variabile variabile impostata a quell’indice.

Il seguente programma usa questa forma dell’istruzione for. La prima regola visita i record in input e tiene nota di quali parole appaiono (almeno una volta) nell’input, memorizzando un 1 nel vettore usate con la parola come indice. La seconda regola visita gli elementi di usate per trovare tutte le parole distinte che appaiono nell’input. Il programma stampa poi ogni parola che è più lunga di 10 caratteri e anche il numero di tali parole. Vedi la sezione Funzioni di manipolazione di stringhe per maggiori informazioni sulla funzione predefinita length().

# Registra un 1 per ogni parola usata almeno una volta
{
    for (i = 1; i <= NF; i++)
        usate[$i] = 1
}

# Trova il numero di parole distinte lunghe più di 10 caratteri
END {
    for (x in usate) {
        if (length(x) > 10) {
            ++numero_parole_lunghe
            print x
        }
    }
    print numero_parole_lunghe, "parole più lunghe di 10 caratteri"
}

Vedi la sezione Generare statistiche sulla frequenza d’uso delle parole per un esempio di questo tipo più dettagliato.

L’ordine nel quale gli elementi del vettore sono esaminati da quest’istruzione è determinato dalla disposizione interna degli elementi del vettore all’interno di awk e nell’awk standard non può essere controllato o cambiato. Questo può portare a dei problemi se vengono aggiunti nuovi elementi al vettore dall’istruzione eseguendo il corpo del ciclo; non è prevedibile se il ciclo for li potrà raggiungere. Similmente, modificare variabile all’interno del ciclo potrebbe produrre strani risultati. È meglio evitare di farlo.

Di sicuro, gawk imposta la lista di elementi su cui eseguire l’iterazione prima che inizi il ciclo, e non la cambia in corso d’opera. Ma non tutte le versioni di awk fanno così. Si consideri questo programma, chiamato vediciclo.awk:

BEGIN {
    a["questo"] = "questo"
    a["è"] = "è"
    a["un"] = "un"
    a["ciclo"] = "ciclo"
    for (i in a) {
        j++
        a[j] = j
        print i
    }
}

Ecco quel che accade quando viene eseguito con gawk (e mawk):

$ gawk -f vediciclo.awk
-| questo
-| ciclo
-| un
-| è

Se si usa invece BWK awk:

$ nawk -f vediciclo.awk
-| ciclo
-| questo
-| è
-| un
-| 1

Successivo: , Precedente: , Su: Fondamenti sui vettori   [Contenuti][Indice]