Neltuosito.itServizi Web Softvision  
 Accesso al Pannello di Controllo :  UserID  Password    Home    Registrazione
 
Servizi per il calcio
  Classifiche Campionati
  Risultati Campionati
Concorsi Pronostici
  Estrazioni Euro Jackpot
  Estrazioni del Lotto
  Risultati SuperEnalotto
  Risultati Totocalcio
  Risultati Totogol
  Risultati Big Match
  Risultati Tris
  Risultati V7
Cucina
Archivio Ricette
  Una Ricetta al Giorno
Vari
Codice Fiscale
  Archivio Barzellette
  Una Barzelletta al Giorno
Calcolo dell'IBAN
Calcolo del Peso Forma
Ricerca CAP
  Calcolo dei Bioritmi
   
Registrazione
Servizi FREE
Assistenza
Suggerimenti
Risorse Web Master
Guida Ajax
  Posizionamento Motori
  Posizionamento e Marketing
  Strategie per i Forum
    

Privacy Policy

Parte seconda: facciamo di meglio

Carino Ajax vero? Ma se pensate a quanto codice abbiamo scritto per fare una mezza richiesta HTTP in Javascript, che abbiamo utilizzato in maniera esplicita una variabile globale, e quanto poco astratto dal reale problema che risolve risulta il nostro codice, non c'è mica da essere orgogliosi... dobbiamo proprio correre ai ripari.

Benvenuti nella seconda parte di questo articolo, dove (se non lo sapete già), imparerete come innalzare il livello del vostro Javascript utilizzando i concetti della Programmazione Funzionale. Se non sapete di cosa si tratta vi consiglio di leggere questa parte anche se non siete interessati a sapere di più su Ajax. In ogni caso i concetti che seguono sono assolutamente necessari per seguire la parte più avanzata dell'articolo, in cui saranno usati per creare una piccola libreria Ajax che ci libera dal tedio di fare tutto a mano, e che sembra integrata nel linguaggio.

Funzioni anonime

Utilizzando linguaggi che sono fondamentalmente imperativi, come il C, Java, PHP, Javascript (anche se l'ultimo come vedremo ha un buon supporto per la programmazione funzionale), una delle cose che capita spesso di fare è quella di scorrere un array indice dopo indice tramite un ciclo for.

Partiamo da un esempio reale... una operazione spesso necessaria è, dato un array, prendere l'elemento col valore massimo. Serve per un sacco di cose, una tra tutte: avete presente la nuova moda web 2.0, di visualizzare dei tag con un font o con un colore proporzionale alla sua popolarità? (più spesso proporzionalmente al logaritmo della popolarità). Bene, la prima cosa che serve per fare la proporzione è ovviamente sapere qual'è il valore del massimo elemento.

In javascript scrivereste abbastanza ovviamente:

var a = Array(10,5,7,81,28);
var max = a[0];
for (i = 1; i < a.length; i++) {
    if (a[i] > max) {
        max = a[i];
    }
}

La fuzione reduce

E se vi serve sapere qual'è la stringa più lunga di un array? Vi serve un altro ciclo for. Una volta un programmatore ha detto Se per ogni ciclo for che ho scritto nella mia vita potessi ricevere un centesimo sarei ricco. Come possiamo liberarci da questa schiavitù del ciclo for? La soluzione è data dal fatto che in Javascript le funzioni sono oggetti di prima classe, che in breve significa che le funzioni così come un oggetto stringa o un numero possono essere passate come argometi ad altre funzioni e ritornate come valore di ritorno da funzioni. In pratica non c'è differenza sostanziale tra quello che si può fare con un numero, con una stringa e con una funzione. Ora abbiamo la soluzione al nostro primo problema, possiamo scrivere una potente funzione che si chiama reduce.

function reduce(a,f) {
    if (a.length == 0) {
        throw emptyArrayError;
    }
    var res = a[0];
    for (var j = 1; j < a.length; j++) {
        res = f(res,a[j]);
    }
    return res;
}

Questa piccola funzione prende in ingresso due oggetti: il primo è un array, il secondo è una funzione f. Applica f ai primi due elementi dell'array, e prende il risultato. Poi applica f al risultato e al terzo elemento dell'array, e così via. in pratica se L'array contiene i valori 1,2,3,4 il risultato di reduce è f(f(f(1,2),3),4).

Come vedete la funzione f che viene passata a reduce prende in input due argomenti, li compara, e ritorna uno dei due. Se f fosse una funzione che dati due argomenti ritorna il più grande dei due, il risultato di reduce(a,f) sarebbe il massimo elemento dell'array! Bene, ora siamo in grado di scrivere del codice che prende l'elemento più grande di un array senza ricorrere ad un clico for usando reduce. Ecco come.

function max(a,b) {
    if (a > b)
        return a;
    else
        return b;
}

var a = Array(10,5,7,81,28);
var max = reduce(a,max);

In pratica abbiamo estrapolato quello che c'è di uguale in molti cicli for e lo abbiamo separato dal resto del codice, incarnandolo nella funzione reduce. Rimane un problema, abbiamo dovuto scrivere la funzione max, e ciò può essere noioso. Ora che abbiamo reduce vorremmo utilizzarla in tanti piccoli contesti quotidiani, e scrivere continuamente funzioni aiutanti è una noia. Ma Javascript non è un linguaggio smidollato! Infatti ha un concetto molto utile, le funzioni anonime. Se in Javascript le funzioni sono oggetti come tutti gli altri, perchè devono avere per forza un nome? Una stringa non ha un nome, neppure un numero. Anche le funzioni possono non averlo, possono essere scritte in maniera "letterale", o messe dentro una variabile, come tutti gli altri tipi di dato. Basta usare la seguente notazione.

var a = Array(10,5,7,81,28);
var maxfunction = function(a,b) { return (a>b) ? a : b };
var max = reduce(a,maxfunction);

Così come Array(1,2,3) ritorna un array, function(parametri) {codice} ritorna una funzione. Dunque nell'esempio sopra abbiamo creato una funzione e abbiamo messo il suo riferimento in una variabile, e poi l'abbiamo usata come argomento di reduce. Ma perchè usare una variabile intermedia? Ecco dunque la versione finale, in tutto il suo splendore ;)

var a = Array(10,5,7,81,28);
var max = reduce(a,function(a,b){return (a>b)?a:b;});

Confrontate questo codice per trovare il massimo elemento di un array con quello che avevamo scritto utilizzando il ciclo for all'inizio. Non solo questo, reduce fa tutto quello che volete... avete voglia di sommare l'array? Bene:

var a = Array(10,5,7,81,28);
var sum = reduce(a,function(a,b){return a+b;});

Il limite è la vostra fantasia.

Le amiche di reduce: map e filter

Anche se per i nostri scopi la cosa importante è la comprensione delle funzioni anonime (che permetteranno di capire cosa sono le chiusure nel prossimo paragrafo), la programmazione funzionale è uno strumento potentissimo, dunque illustro brevemente altre due classiche primitive della programmazione funzionale, map e filter.

Come reduce anche map prende come input un array e una funzione f, ma invece che ridurre l'array ad un solo elemento applicando una funzione come fa reduce, map ritorna un nuovo array in cui ogni elemento è stato ottenuto trasformando il vecchio elemento nel nuovo tramite una funzione f.

In termini pratici, dato l'array 1,2,4,7 ciò che ritorna map(a,f) è f(1),f(2),f(4),f(7). Ecco la funzione map.

function map(a,f) {
    var res = Array();
    for (var j = 0; j < a.length; j++) {
        res[j] = f(a[j]);
    }
    return res;
}

Questa volta la funzione f che passiamo come argomento a map è una funzione che prende un solo argomento (una funzione unaria), e ritorna un valore. Ecco un esempio di applicazione di map, che non fa altro che trasformare un array di numeri in un array dei quadrati di tali numeri.

var a = Array(1,5,4,3);
var b = map(a,function(x){return x*x});

Alla fine del programma l'array b conterrà gli elementi 1,25,16,9. Come potete immaginare è possibile sommare gli effetti di map e reduce, ad esempio provate a scrivere il codice che utilizzando queste due primitive sommi i quadrati degli elementi di un array. Si noti come anche se teoricamente siamo interessati soltanto al valore di ritorno della funzione f, sia possible forzare map a lavorare come una sorta di foreach.

var a = Array(1,5,4,3);
map(a,alert);

Queste due righe di codice avranno l'effetto di fare l'alert di tutti gli elementi dell'array. Il risultato della funzione map non viene utilizzato in nessun modo perchè; non è nostro scopo, in questo caso siamo solo interessati nell'effetto collaterale (o side effect) che ha la chiamata della funzione f (ovvero alert), che è quello di visualizzare i numeri.

L'ultima delle funzioni che giocano un ruolo importante tra le primitive della programmazione funzionale su cui ci soffermeremo è filter. Questa funzione sarà solo descritta in quanto concettualmente molto simile alle altre due. L'implementazione di filter è lasciata come esercizio al lettore. Ma cosa fa filter? Dato un Array e una funzione unaria f in ingresso, ritorna un Array composto solo dagli elementi per cui la chiamata alla funzione f restituisce true. In pratica filter filtra l'array e ne crea uno che ha come elementi solo quelli che piacciono alla funzione passata come argomento, che utilizza il valore di ritorno true o false per indicare se tenere o scartare ogni dato elemento

Utilizzando assieme map, filter e reduce è per esempio possibile in una singola linea di codice processare un array per tenere solo gli elementi che sono maggiori di 10, elevarli al quadrato e ottenerne la somma. Ma ora è tempo di chiudere questa (spero interessante) parentesi e continuare il nostro breve incontro delle caratteristiche evolute di Javascript.

 


 

 

 

 

Softvision - Via Cesare Battisti, 101 - 67051 Avezzano (AQ) - P.IVA 02081660660

Privacy Policy - Cookie Policy