Sei sulla pagina 1di 33

Corso di Informatica Multimediale

Programmazione con l’ordine superiore in JavaScript

Marco Comini

2021-11-11
Higher-order: introduzione

Definizione
Una funzione di ordine superiore (o funzione higher-order) è una funzione che può
prendere altre funzioni come parametri e/o restituire funzioni come risultato.

Tutti (o quasi) i linguaggi ammettono funzioni come parametri.


Meno frequente poter restituire funzioni come risultato.
JavaScript lo permette!

Marco Comini Informatica Multimediale 2021-11-11 1 / 19


Higher-order: le variabili non-locali/1

Le variabili non-locali usate da una funzione restituita come parametro sono quelle
previste dallo scoping statico e continuano ad esistere anche se la funzione che le
aveva create è terminata?
1 var variable = " top - level " ;
2 function parentFunction () {
3 var variable = " local " ;
4 function childFunction () {
5 print ( " childFunction : variable = " + variable );
6 }
7 return childFunction ;
8 }
9

10 var child = parentFunction ();


11 child ();

Marco Comini Informatica Multimediale 2021-11-11 2 / 19


Higher-order: le variabili non-locali/2
Per uno stesso nome di variabile non-locale usata da una funzione restituita come
parametro abbiamo sempre la stessa locazione di memoria oppure è una diversa
per ogni chiamata?
1 var variable = " top - level " ;
2 function parentFunction ( x ) {
3 var variable = " local ( " + x + " ) " ;
4 function childFunction () {
5 variable += " A " ;
6 print ( " childFunction : variable = " + variable );
7 }
8 return childFunction ;
9 }
10

11 var child1 = parentFunction (1);


12 child1 ();
13 var child2 = parentFunction (2);
14 child2 ();
15 child1 ();
Marco Comini Informatica Multimediale 2021-11-11 3 / 19
Higher-order: le variabili non-locali/3

Ecco un esempio che sfrutta utilmente questo meccanismo.


1 function makeAddFunction ( amount ) {
2 function add ( number ) {
3 return number + amount ;
4 }
5 return add ;
6 }
7

8 var addTwo = makeAddFunction (2);


9 var addFive = makeAddFunction (5);
10 show ( addTwo (1) + addFive (2));

Marco Comini Informatica Multimediale 2021-11-11 4 / 19


JavaScript: sintassi alternativa definizione funzioni/1

Espressioni di tipo funzione


In JavaScript possiamo esprimere direttamente delle funzioni, cioè scrivere
delle espressioni il cui valore è una funzione.
Non è quindi necessario definire una funzione prima di poterla passare come
argomento o per restituirla come valore. Ad esempio
return ( function (a , b ) { return a * b ;} );
Un’espressione di tipo funzione può essere memorizzata in una variabile. È un
metodo alternativo per definire una funzione. Al contrario di una definizione
“tradizionale” il legame può essere cambiato.
var f = function ( x ) { return x * x ;};
var f = function (a , b ) { return a * b ;};
Dopo che un’espressione di funzione è stata memorizzata in una variabile, la
variabile può essere utilizzata come ogni funzione:
var z = f (4 , 3);

Marco Comini Informatica Multimediale 2021-11-11 5 / 19


JavaScript: sintassi alternativa definizione funzioni/2
Arrow Functions Abbiamo una sintassi alternativa che permette di esprimere
funzioni che restituiscono solo un valore senza usare la parola chiave
function , la parola chiave return e le parentesi graffe.
Ad esempio, invece di
function (a , b ) { return a * b ;}
si può scrivere solo
(a , b ) = > a * b
Altre due definizioni equivalenti per makeAddFunction sono
function makeAddFunction ( amount ) {
return function ( number ) {
return number + amount ;
};
}
function makeAddFunction ( amount ) {
return ( number ) = > number + amount ;
}
Marco Comini Informatica Multimediale 2021-11-11 6 / 19
JavaScript: metodi di ordine superiore degli array/1
find( predicate )
Restituisce il valore del primo elemento in un array che soddisfa predicate
(cioè su cui predicate vale truthy).
Tecnicamente predicate non deve obbligatoriamente essere un predicato, cioè
una funzione a valori booleani, ma i suoi risultati vengono partizionati in
truthy/falsy.
findIndex( predicate )
Restituisce l’indice del primo elemento in un array che soddisfa predicate.
1 var numArr = [1 , 22 , 0 , 3];
2 show ( numArr . find ( ( x )= > x >= 2 ));
3 show ( numArr . findIndex ( ( x )= > x >= 3 ));
4 show ( numArr . find ( ( x )= > x == 4 ));
5 show ( numArr . findIndex ( ( x )= > x == undefined ));
6

7 var strArr = [ " aa " , " bb " , " ccc " , " " , " dddd " ];
8 show ( strArr . find ( ( x )= > x . length >2 ));
9 show ( strArr . findIndex ( ( x )= > x . length >2 ));
Marco Comini Informatica Multimediale 2021-11-11 7 / 19
JavaScript: metodi di ordine superiore degli array/2

every( predicate )
Controlla se ogni elemento in un array soddisfa predicate
some( predicate )
Controlla se almeno uno degli elementi in un array soddisfa predicate
1 const f = ( x )= > x >= 2;
2 var numArr = [1 , 22 , 0 , 3];
3 show ( numArr . every ( f ));
4 show ( numArr . some ( f ));

filter( predicate )
Crea un nuovo array con ogni elemento in un array che soddisfa predicate
1 var numArr = [1 , 22 , 0 , 3];
2 show ( numArr . filter ( ( x )= > x >= 2 ));
3 var strArr = [ " aa " , " bb " , " ccc " , " " , " dddd " ];
4 show ( strArr . filter ( ( x )= > x . length >2 ));

Marco Comini Informatica Multimediale 2021-11-11 8 / 19


JavaScript: metodi di ordine superiore degli array/3

map( function )
Crea un nuovo array con il risultato della chiamata di una funzione su ogni
elemento di un array

[v1 , . . . , vn ].map(f ) = [f (v1 ), . . . , f (vn )]

1 var numArr = [1 , 22 , 0 , 3];


2 show ( numArr . map ( ( x )= > x >= 2 ));
3 show ( numArr . map ( ( x )= > x + 2 ));
4 show ( numArr . map ( ( x )= > " a " + x ));

Marco Comini Informatica Multimediale 2021-11-11 9 / 19


JavaScript: metodi di ordine superiore degli array/4

reduce( binary-function , init-value )


“Riduce” i valori di un array a un singolo valore, partendo da init-value e
usando iterativamente la funzione binary-function con gli elementi dell’array,
procedendo da sinistra a destra.

[v1 , . . . , vn ].reduce(f, x0 ) = xn

dove ∀1 ≤ i ≤ n. xi = f (xi−1 , vi )

Per esempio

[v1 , v2 , v3 ].reduce(f, z) = f (f (f (z, v1 ), v2 ), v3 )

1 function arraySum ( a ) {
2 return a . reduce ( (x , y )= > x +y , 0 );
3 }

Marco Comini Informatica Multimediale 2021-11-11 10 / 19


JavaScript: metodi di ordine superiore degli array/5

reduceRight( binary-function , init-value )


“Riduce” i valori di un array a un singolo valore, partendo da init-value e
usando iterativamente la funzione binary-function con gli elementi dell’array,
procedendo da destra a sinistra.

[v1 , . . . , vn ].reduceRight(f, x0 ) = xn

dove ∀1 ≤ i ≤ n. xi = f (xi−1 , vn−i+1 )

Per esempio

[v1 , v2 , v3 ].reduce(f, z) = f (f (f (z, v3 ), v2 ), v1 )

1 function arraySum ( a ) {
2 return a . reduceRight ( (x , y )= > x +y , 0 );
3 }

Marco Comini Informatica Multimediale 2021-11-11 11 / 19


JavaScript: metodi di ordine superiore degli array/6
Esempi reduce / reduceRight
1 var numArr = [1300 , 222 , 3];
2 var strArr = [ " aa " , " bb " , " cc " ];
3 const add = (a , b ) = > a + b ;
4

5 print ( " es 1 " );


6 show ( numArr . reduce ( add ,0));
7

8 print ( " es 2 " );


9 show ( numArr . reduceRight ( add ,0));
10

11 print ( " es 3 " );


12 show ( strArr . reduce ( add , " " ));
13 show ( numArr . reduce ( add , " " ));
14

15 print ( " es 4 " );


16 show ( strArr . reduceRight ( add , " " ));
17 show ( numArr . reduceRight ( add , " " ));
Marco Comini Informatica Multimediale 2021-11-11 12 / 19
JavaScript: metodi di ordine superiore degli array/7
Altri esempi reduce / reduceRight
1 var numArr = [1300 , 222 , 53 , 35];
2

3 print ( " es 5 " );


4 show ( numArr . reduce ( (a , b ) = > a + " " +b , " " ));
5 show ( numArr . reduceRight ( (a , b ) = > a + " " +b , " " ));
6

7 print ( " es 6 " );


8 show ( numArr . reduce ( (a , b )= > Math . max (a , b ) ,
9 Number . MIN_SAFE_INTEGER ));
10 show ( numArr . reduceRight ( (a , b )= > Math . max (a , b ) ,
11 Number . MIN_SAFE_INTEGER ));
12

13 print ( " es 7 " );


14 show ( numArr . reduce ( (a , b )= > Math . min (a , b ) ,
15 Number . MAX_SAFE_INTEGER ));
16 show ( numArr . reduceRight ( (a , b )= > Math . min (a , b ) ,
17 Number . MAX_SAFE_INTEGER ));
Marco Comini Informatica Multimediale 2021-11-11 13 / 19
JavaScript: metodi di ordine superiore degli array/8

Ulteriori esempi reduce / reduceRight


1 var numArr = [1300 , 222 , 53 , 35];
2

3 print ( " es 8 " );


4 show ( numArr . reduceRight (
5 (a , b ) = > { a . push ( b ); return a ; } , []));
6 show ( numArr . reduce (
7 function (a , b ) { a . push ( b ); return a ; } , []));
8

9 print ( " es 9 " );


10 show ( numArr . reduce ( function (a , b ) {
11 if ( a . length % 2 == 0 && b > 10 ) {
12 a . push ( b ); }
13 return a ;
14 } , []));

Marco Comini Informatica Multimediale 2021-11-11 14 / 19


JavaScript: metodi di ordine superiore degli array/9
Invece di due cicli annidati per lavorare su matrici
1 function matrixRowsMin ( mat ) {
2 var v = [];
3 v . length = mat . length ;
4 v . fill ( Number . MAX_SAFE_INTEGER );
5 for ( var j in v ) {
6 for ( var k in mat [ j ]) {
7 v [ j ] = Math . min ( v [ j ] , mat [ j ][ k ]);
8 }
9 }
10 return v ;
11 }
si può usare map e reduce / reduceRight
1 const matrixRowsMin = ( mat ) = >
2 mat . map ( ( row ) = >
3 row . reduce ( (a , b ) = > Math . min (a , b ) ,
4 Number . MAX_SAFE_INTEGER )
5 )
Marco Comini Informatica Multimediale 2021-11-11 15 / 19
Alcuni test/1

Quale valore assume l’array b dopo l’esecuzione del seguente frammento di


codice?
1 var a = [ -2 ,6];
2 a . push (4);
3 a . reverse ();
4 var b = [ a [1]]. concat (a , [0]);
1 "646-20"
2 [6, 0]
3 [4, 6, -2, 8]
4 [6, 4, 6, -2, 0]
5 [[6], [4, 6, -2], [0]]
6 [[6, 4, 6, -2], [6, 0]]
7 nessuna delle opzioni elencate

Marco Comini Informatica Multimediale 2021-11-11 16 / 19


Alcuni test/1

Quale valore assume l’array b dopo l’esecuzione del seguente frammento di


codice?
1 var a = [ -2 ,6];
2 a . push (4);
3 a . reverse ();
4 var b = [ a [1]]. concat (a , [0]);
1 "646-20"
2 [6, 0]
3 [4, 6, -2, 8]
✓ [6,
4 4, 6, -2, 0]
5 [[6], [4, 6, -2], [0]]
6 [[6, 4, 6, -2], [6, 0]]
7 nessuna delle opzioni elencate

Marco Comini Informatica Multimediale 2021-11-11 16 / 19


Alcuni test/2

Determinare l’output (in console) del seguente codice JavaScript.


1 var a =66 , b =37 , v =[22 ,17];
2 function f (b ,c , d ) {
3 function g ( c ) {
4 var a =31;
5 d [1] += 3;
6 v [0] += 2;
7 a += 11;
8 c += 3;
9 return ( b + c ); }
10 a += 5;
11 b += 2;
12 c += 7;
13 return ( g ( c )+ b + c + d [1]); }
14 console . log ( f (a -b , v [0] , v )+ a + b + v [0]+ v [1]);

Marco Comini Informatica Multimediale 2021-11-11 17 / 19


Alcuni test/2

Determinare l’output (in console) del seguente codice JavaScript.


1 var a =66 , b =37 , v =[22 ,17];
2 function f (b ,c , d ) {
3 function g ( c ) {
4 var a =31;
5 d [1] += 3;
6 v [0] += 2;
7 a += 11;
8 c += 3;
9 return ( b + c ); }
10 → a += 5;
11 b += 2;
12 c += 7;
13 return ( g ( c )+ b + c + d [1]); }
14 console . log ( f (a -b , v [0] , v )+ a + b + v [0]+ v [1]);
PRIMA bf ==29, cf ==22, df ==v==[22,17], a == 66
DOPO a == 71
Marco Comini Informatica Multimediale 2021-11-11 17 / 19
Alcuni test/2

Determinare l’output (in console) del seguente codice JavaScript.


1 var a =66 , b =37 , v =[22 ,17];
2 function f (b ,c , d ) {
3 function g ( c ) {
4 var a =31;
5 d [1] += 3;
6 v [0] += 2;
7 a += 11;
8 c += 3;
9 return ( b + c ); }
10 a += 5;
11 → b += 2;
12 c += 7;
13 return ( g ( c )+ b + c + d [1]); }
14 console . log ( f (a -b , v [0] , v )+ a + b + v [0]+ v [1]);
bf == 31

Marco Comini Informatica Multimediale 2021-11-11 17 / 19


Alcuni test/2

Determinare l’output (in console) del seguente codice JavaScript.


1 var a =66 , b =37 , v =[22 ,17];
2 function f (b ,c , d ) {
3 function g ( c ) {
4 var a =31;
5 d [1] += 3;
6 v [0] += 2;
7 a += 11;
8 c += 3;
9 return ( b + c ); }
10 a += 5;
11 b += 2;
12 → c += 7;
13 return ( g ( c )+ b + c + d [1]); }
14 console . log ( f (a -b , v [0] , v )+ a + b + v [0]+ v [1]);
cf == 29

Marco Comini Informatica Multimediale 2021-11-11 17 / 19


Alcuni test/2

Determinare l’output (in console) del seguente codice JavaScript.


1 var a =66 , b =37 , v =[22 ,17];
2 function f (b ,c , d ) {
3 function g ( c ) {
4 → var a =31;
5 d [1] += 3;
6 v [0] += 2;
7 a += 11;
8 c += 3;
9 return ( b + c ); }
10 a += 5;
11 b += 2;
12 c += 7;
13 return ( g ( c )+ b + c + d [1]); }
14 console . log ( f (a -b , v [0] , v )+ a + b + v [0]+ v [1]);
cg == 29, ag ==31

Marco Comini Informatica Multimediale 2021-11-11 17 / 19


Alcuni test/2

Determinare l’output (in console) del seguente codice JavaScript.


1 var a =66 , b =37 , v =[22 ,17];
2 function f (b ,c , d ) {
3 function g ( c ) {
4 var a =31;
5 → d [1] += 3;
6 v [0] += 2;
7 a += 11;
8 c += 3;
9 return ( b + c ); }
10 a += 5;
11 b += 2;
12 c += 7;
13 return ( g ( c )+ b + c + d [1]); }
14 console . log ( f (a -b , v [0] , v )+ a + b + v [0]+ v [1]);
df ==v==[22,20]

Marco Comini Informatica Multimediale 2021-11-11 17 / 19


Alcuni test/2

Determinare l’output (in console) del seguente codice JavaScript.


1 var a =66 , b =37 , v =[22 ,17];
2 function f (b ,c , d ) {
3 function g ( c ) {
4 var a =31;
5 d [1] += 3;
6 → v [0] += 2;
7 a += 11;
8 c += 3;
9 return ( b + c ); }
10 a += 5;
11 b += 2;
12 c += 7;
13 return ( g ( c )+ b + c + d [1]); }
14 console . log ( f (a -b , v [0] , v )+ a + b + v [0]+ v [1]);
v==[24,20]

Marco Comini Informatica Multimediale 2021-11-11 17 / 19


Alcuni test/2

Determinare l’output (in console) del seguente codice JavaScript.


1 var a =66 , b =37 , v =[22 ,17];
2 function f (b ,c , d ) {
3 function g ( c ) {
4 var a =31;
5 d [1] += 3;
6 v [0] += 2;
7 → a += 11;
8 c += 3;
9 return ( b + c ); }
10 a += 5;
11 b += 2;
12 c += 7;
13 return ( g ( c )+ b + c + d [1]); }
14 console . log ( f (a -b , v [0] , v )+ a + b + v [0]+ v [1]);
ag ==42

Marco Comini Informatica Multimediale 2021-11-11 17 / 19


Alcuni test/2

Determinare l’output (in console) del seguente codice JavaScript.


1 var a =66 , b =37 , v =[22 ,17];
2 function f (b ,c , d ) {
3 function g ( c ) {
4 var a =31;
5 d [1] += 3;
6 v [0] += 2;
7 a += 11;
8 → c += 3;
9 return ( b + c ); }
10 a += 5;
11 b += 2;
12 c += 7;
13 return ( g ( c )+ b + c + d [1]); }
14 console . log ( f (a -b , v [0] , v )+ a + b + v [0]+ v [1]);
cg == 32

Marco Comini Informatica Multimediale 2021-11-11 17 / 19


Alcuni test/2

Determinare l’output (in console) del seguente codice JavaScript.


1 var a =66 , b =37 , v =[22 ,17];
2 function f (b ,c , d ) {
3 function g ( c ) {
4 var a =31;
5 d [1] += 3;
6 v [0] += 2;
7 a += 11;
8 c += 3;
9 → return ( b + c ); }
10 a += 5;
11 b += 2;
12 c += 7;
13 return ( g ( c )+ b + c + d [1]); }
14 console . log ( f (a -b , v [0] , v )+ a + b + v [0]+ v [1]);
returng == bg +cg == 63

Marco Comini Informatica Multimediale 2021-11-11 17 / 19


Alcuni test/2

Determinare l’output (in console) del seguente codice JavaScript.


1 var a =66 , b =37 , v =[22 ,17];
2 function f (b ,c , d ) {
3 function g ( c ) {
4 var a =31;
5 d [1] += 3;
6 v [0] += 2;
7 a += 11;
8 c += 3;
9 return ( b + c ); }
10 a += 5;
11 b += 2;
12 c += 7;
13 → return ( g ( c )+ b + c + d [1]); }
14 console . log ( f (a -b , v [0] , v )+ a + b + v [0]+ v [1]);
returnf == 63+bf +cf +d[1] == 143

Marco Comini Informatica Multimediale 2021-11-11 17 / 19


Alcuni test/2

Determinare l’output (in console) del seguente codice JavaScript.


1 var a =66 , b =37 , v =[22 ,17];
2 function f (b ,c , d ) {
3 function g ( c ) {
4 var a =31;
5 d [1] += 3;
6 v [0] += 2;
7 a += 11;
8 c += 3;
9 return ( b + c ); }
10 a += 5;
11 b += 2;
12 c += 7;
13 return ( g ( c )+ b + c + d [1]); }
14 →console . log ( f (a -b , v [0] , v )+ a + b + v [0]+ v [1]);
143+a+b+v[0]+v[1] == 143+71+37+24+20 == 295

Marco Comini Informatica Multimediale 2021-11-11 17 / 19


Alcuni test/3

Sia E l’espressione JavaScript


1 document . g et El em e n t s B y T a g N am e ( " p " ). length
In una pagina web che contenga 2 paragrafi, se E viene inserita
rispettivamente prima, in mezzo o dopo i suddetti paragrafi il suo valore è
rispettivamente
1 sempre 2
2 sempre 0
3 sempre un array con i 2 paragrafi presenti nella pagina
4 0, 1, 2

Marco Comini Informatica Multimediale 2021-11-11 18 / 19


Alcuni test/3

Sia E l’espressione JavaScript


1 document . g et El em e n t s B y T a g N am e ( " p " ). length
In una pagina web che contenga 2 paragrafi, se E viene inserita
rispettivamente prima, in mezzo o dopo i suddetti paragrafi il suo valore è
rispettivamente
1sempre 2
2sempre 0
3 sempre un array con i 2 paragrafi presenti nella pagina


4 0, 1, 2

Marco Comini Informatica Multimediale 2021-11-11 18 / 19


Alcuni test/4
Avendo queste dichiarazioni
1 var matrix = [[1 ,2 ,0] , [0 ,0 ,2] , [4 ,3 ,2] ,
2 [1 ,2 ,3] , [0 ,0 ,0]];
3 function g ( row ) {
4 return row . reduce ( (a , b )= > Math . max (a , b ) ,
5 Number . MIN_SAFE_INTEGER ) > 2;
6 }
1 La chiamata
1 matrix . find ( g )
cosa produce?
2 La chiamata
1 matrix . some ( g )
cosa produce?
3 La chiamata
1 matrix . filter ( g )
cosa produce?
Marco Comini Informatica Multimediale 2021-11-11 19 / 19

Potrebbero piacerti anche