0 commenti php

Filtrare gli array è una di quelle operazioni che siamo chiamati a svolgere frequentemente quando abbiamo a che fare con questa tipologia di dato.

Per questi scopi due sono le funzioni chiave che si potranno impiegare: array_filter() e array_map().

 

Infatti, al termine "filtrare" si riconducono scopi spesso diversissimi. I casi più frequenti sono solitamente due:

applicare una determinata funzione a tutti gli elementi dell'array; in questo caso la funzione che farà al nostro caso sarà array_map();

eliminare da un array gli elementi il cui valore non soddisfa certi criteri; in questo caso la funzione che farà al caso nostro è array_filter();

 

Un'ulteriore ipotesi si ha con la combinazione delle due tipologie di "filtro": ad esempio eliminare dall'array (con array_filter) gli elementi che dopo l'applicazione di una funzione (con array_map) non soddisfano certi criteri.

 

Analizziamo separatamente le due funzioni.

 

 

ARRAY_MAP 

La funzione array_map ha lo scopo di modificare il valore di ogni elemento dell'array applicando ad ognuno di essi una funzione a nostra scelta.

Essa richiede due parametri:

  1. la funzione di callback, ovvero quella che dovrà essere applicata a tutti gli elementi dell'array;
  2. l'array da sottoporre a tale filtro.

 

Ad esempio poniamo di voler applicare la funzione intval() a tutti gli elementi dell'array: i valori non numerici saranno "trasformati" in zero. Avremo:

<?php
$array_test = array(
		'stringa',
		3,
		0,
		'',
		array(),
		8,
		FALSE
		); 

$array_filtrato = array_map("intval", $array_test);
print_r($array_filtrato);
/*
Output
Array
(
    [0] => 0
    [1] => 3
    [2] => 0
    [3] => 0
    [4] => 0
    [5] => 8
    [6] => 0
)
*/
?>

 

 

ARRAY_FILTER

Array_filter() restituisce l'array escludendo gli elementi che non rispettano i criteri definiti dalla funzione di callback preservando le chiavi dell'array.

Essa prevede due parametri di cui il secondo è opzionale:

  1. l'array che si desidera filtrare;
  2. la funzione di callback.

 

Vediamone il funzionamento a seconda che venga utilizzata con uno o due parametri.

 

In caso si utilizzi array_filter() con un unico parametro la funzione escluderà dall'array i valori che sono:

  1. valore stringa vuota;
  2. valore numerico pari a 0 (zero);
  3. valore boleano FALSE;
  4. NULL;
  5. array vuoto;

 

Cioè vengono escluse le variabili cui la funzione empty() darebbe TRUE.

Vediamone un esempio:

<?php
$array_test = array(
		'stringa',
		3,
		0,
		'',
		array(),
		8,
		FALSE
		); 

$array_filtrato = array_filter($array_test);
print_r($array_filtrato);
/*
Output
Array
(
    [0] => stringa
    [1] => 3
    [5] => 8
)
*/
?>

 

 

Impiegando anche il secondo parametro, cioè la funzione di callback, potremo definire il filtro che vogliamo applicare all'array: saranno esclusi gli elementi ai quali applicando la funzione di callback questa darà come return FALSE.

Nel precedente esempio, infatti, i valori esclusi sono predefiniti dalla funzione (le stringhe vuote, numeri pari a zero, etc etc.). Se invece vogliamo definire un nostro criterio di filtraggio (esclusione) dovremo, appunto, specificarlo tramite la funzione di callback.

Chiariamo con un esempio. Poniamo di avere sempre lo stesso $array_test e desideriamo escludere da esso i valori che non sono numeri.

 

Per fare tale verifica si dovrà applicare la funzione is_numeric() (nativa di php) a ciascun elemento. La funzione is_numeric restituisce un valore bolenano, TRUE se è un numero, FALSE negli altri casi.

Ebbene, impostando is_numeric come secondo parametro di array_filter si avrà che la funzione is_numeric verrà applicata a ciascun elemento dell'array e, se darà FALSE (ovvero se il valore non è un numero), tale elemento sarà escluso dal nostro $array_test.

<?php
$array_test = array(
		'stringa',
		3,
		0,
		'',
		array(),
		8,
		FALSE
		); 

$array_filtrato = array_filter($array_test, "is_numeric");
print_r($array_filtrato);
/*
Output
Array
(
    [1] => 3
    [2] => 0
    [5] => 8
)
*/
?>

 

Si noti che rispetto al caso precedente lo zero non è stato escluso: esso è un numero a tutti gli effetti e quindi is_numeric ci darà TRUE.

 

Alle volte, le nostre specifiche esigenze possono rendere necessario fissare un nostro specifico criterio di filtraggio non riconducibile ad una funzione nativa di php.

In questi casi dovremo creare una nostra funzione di callback da passare come parametro di array_filter(): questa potrà essere più o meno complessa ma dovra avere un return di natura boleana e in particolare dovrà restituire FALSE applicata agli elementi dell'array che desideriamo escludere.

 

Facciamo un esempio: poniamo di voler escludere dall'array tutti i valori non numerici e che, inoltre, siano superiori a 5; andremo a creare una funzione che chiamaremo, ad esempio, my_filtro().

<?php
function my_filtro($val)
	{
	// se non è un numero return FALSE
	if(!is_numeric($val)){
		return FALSE;
		}
	// se il numero è superiore a 5 return FALSE
	else if($val>5){
		return FALSE;
		}
	// altrimenti return TRUE
	else{
		return TRUE;
		}
	}

$array_test = array(
		'stringa',
		3,
		0,
		'',
		array(),
		8,
		FALSE
		); 

$array_filtrato = array_filter($array_test, "my_filtro");
print_r($array_filtrato);
/*
Output
Array
(
    [1] => 3
    [2] => 0
)
*/
?>

 

Come possiamo notare sono stati esclusi non solo gli elementi con valori non numerici ma anche quelli che sono superiori a 5 (ovvero l'elemento con valore 8).

 

 

VERISIONI RECURSIVE DI ARRAY_FILTER E ARRAY_MAP

Nel caso in cui abbiamo a che fare con array multidimensionali e per applicare il filtro a tutti i valori annidati in sub-array sarà necessario ricorrere a funzioni recursive.

Riporto di seguito le versioni recursive di array_filter e array_map:

 

<?php
function array_filter_recursive($input, $callback = null){
	$array = array();
	foreach ($input as $key => $value){
		if(is_array($value)){
			$value = array_filter_recursive($value, $callback);
			$array[$key] = $value;
			}
		else{
			$function_callback = ($callback!=null AND function_exists($callback)) ? $callback : 'empty';
			$bool = call_user_func($function_callback, $value);
			if($bool!=FALSE)
				{
				$array[$key] = $value;
				}
			}
		}
	return $array;
	}

function array_map_recursive($callback, $input){
	$array = array();
	foreach ($input as $key => $value){
		if(is_array($value)){
			$value = array_map_recursive($callback, $value);
			$array[$key] = $value;
			}
		else{
			$new_value = call_user_func($callback, $value);
			$array[$key] = $new_value;
			}
		}
	return $array;
	} 
?>

 

Olimpio Romanella

Sono un appassionato di Web Developing con un particolare debole per php. Mi dedico principalmente dello sviluppo back-end ed in particolare programmazione lato server con php, sviluppo di database relazionali MySql e progettazione di CMS di piccole e medie dimensioni.

Mi avvalgo del framework javascript Jquery, utilizzando molti dei suoi plugin e nei dei miei progetti utilizzo spesso il framework MVC Codeigniter.

0 Commenti presenti