2012-03-27 13 views
15

Non riesco a trovare una soluzione semplice e diretta al vecchio problema di rimuovere elementi vuoti dagli array in PHP.Rimuove in modo ricorsivo elementi vuoti e sottoarray da una matrice multidimensionale

La mia matrice di ingresso può apparire come segue:

Array ([0] => Array ([Name] => [EmailAddress] =>)) 

(E così via, se non c'è più dati, anche se non ci può essere ...)

Se sembra che quanto sopra, voglio che sia completamente vuoto dopo che l'ho elaborato.

Così print_r($array); sarebbe uscita:

Array () 

Se corro $arrayX = array_filter($arrayX); ancora ottengo lo stessoprint_r uscita . Ovunque ho cercato, questo è il modo più semplice per rimuovere elementi di array vuoti in PHP5, comunque.

Ho anche provato $arrayX = array_filter($arrayX,'empty_array'); ma ho ottenuto il seguente errore:

Warning: array_filter() [function.array-filter]: The second argument, 'empty_array', should be a valid callback

Che cosa sto facendo di sbagliato?

+0

array_filter è impostato per gli array 1D. –

+0

Puoi fornire un input di esempio, con l'output atteso per favore? Ci sono diversi modi di interpretare la tua domanda, * "Se sembra quanto sopra, io voglio che sia completamente vuoto dopo che l'avremo elaborata." * Mi sta gettando via, vuoi che sia totalmente andato o essere un array vuoto? –

+0

Questo è un array multidimensionale. array_filter funziona solo in una dimensione. È necessario scorrere l'array e applicare array_filter a ogni iterazione prima. – Nilpo

risposta

21

Provare a utilizzare array_map() per applicare il filtro per ogni array in $array:

$array = array_map('array_filter', $array); 
$array = array_filter($array); 

Demo: http://codepad.org/xfXEeApj

+1

attendere Si, ha fatto si desidera rimuovere l'intero array solo se * Tutti gli articoli * sono vuoti ? Questo non è ciò che fa. Puoi fornire un input di esempio, con l'output atteso per favore? –

+1

No. Questo non funziona: -/ –

+0

Secondo la tua domanda e il chiarimento nei commenti, sì dovrebbe: http://codepad.org/FdfY5aqj Quando tutti gli elementi vuoti vengono rimossi, si finisce con un array vuoto. Se questo non è quello che vuoi, per favore fornisci qualche esempio di input con l'output atteso. Sei preoccupato dell'effetto collaterale della rimozione dei vuoti dagli altri array? –

7

Esistono numerosi esempi su come eseguire questa operazione. Puoi provare lo docs, per uno (vedi il primo commento).

function array_filter_recursive($array, $callback = null) { 
    foreach ($array as $key => & $value) { 
     if (is_array($value)) { 
      $value = array_filter_recursive($value, $callback); 
     } 
     else { 
      if (! is_null($callback)) { 
       if (! $callback($value)) { 
        unset($array[$key]); 
       } 
      } 
      else { 
       if (! (bool) $value) { 
        unset($array[$key]); 
       } 
      } 
     } 
    } 
    unset($value); 

    return $array; 
} 

Certo questo esempio non effettivamente utilizzare array_filter, ma si ottiene il punto.

+0

Questo codice non è stato in grado di disinserire la matrice più profonda di lunghezza 0, e non è riuscito a seguire e cancellare la struttura a tripla-nested è stato nel – CodedMonkey

3

Seguendo il suggerimento jeremyharris', questo è il modo in cui avevo bisogno di cambiarlo per farlo funzionare:

function array_filter_recursive($array) { 
    foreach ($array as $key => &$value) { 
     if (empty($value)) { 
     unset($array[$key]); 
     } 
     else { 
     if (is_array($value)) { 
      $value = array_filter_recursive($value); 
      if (empty($value)) { 
       unset($array[$key]); 
      } 
     } 
     } 
    } 

    return $array; 
} 
4

La risposta accettata non fa esattamente quello che l'OP ha chiesto. Se si desidera rimuovere ricorsivamente tutti i valori che restituiscono falsi compresi gli array vuoti quindi utilizzare la seguente funzione:

function array_trim($input) { 
    return is_array($input) ? array_filter($input, 
     function (& $value) { return $value = array_trim($value); } 
    ) : $input; 
} 

Oppure si potrebbe cambiare il ritorno di circostanza in base alle proprie esigenze, ad esempio:

{ return !is_array($value) or $value = array_trim($value); } 

Se si desidera rimuovere solo gli array vuoti. Oppure puoi cambiare la condizione per testare solo per "" o false o null, ecc ...

2

Prova con:

$array = array_filter(array_map('array_filter', $array)); 

Esempio:

$array[0] = array(
    'Name'=>'', 
    'EmailAddress'=>'', 
); 
print_r($array); 

$array = array_filter(array_map('array_filter', $array)); 

print_r($array); 

uscita:

Array 
(
    [0] => Array 
     (
      [Name] => 
      [EmailAddress] => 
     ) 
) 

Array 
(
) 
0

array_filter() non è di tipo sensibile per impostazione predefinita. Ciò significa che qualsiasi zero ish, falso-y, verranno rimossi nulli, valori vuoti. I miei collegamenti da seguire dimostreranno questo punto.

matrice di ingresso del campione del PO è 2-dimensionale. Se la struttura dei dati è statica, la ricorsione non è necessaria. Per tutti coloro che desiderano filtrare i valori di lunghezza zero da una matrice multidimensionale, fornirò un metodo statico 2-dim e un metodo ricorsivo.

statico 2-dim Array: Questo codice esegue un filtro "zero-safe" sugli elementi 2 ° livello e quindi rimuove sottoarray vuoti: (See this demo to see this method work with different (trickier) array data)

$array=[ 
    ['Name'=>'','EmailAddress'=>''] 
]; 

var_export(
    array_filter( // remove the 2nd level in the event that all subarray elements are removed 
     array_map( // access/iterate 2nd level values 
      function($v){ 
       return array_filter($v,'strlen'); // filter out subarray elements with zero-length values 
      },$array // the input array 
     ) 
    ) 
); 

Ecco lo stesso codice una battuta:

var_export(array_filter(array_map(function($v){return array_filter($v,'strlen');},$array))); 

uscita (come originariamente specificato dal OP):

array (
) 

* se non si desidera rimuovere i sottoarray vuote, è sufficiente rimuovere il esterna array_filter() chiamata.


metodo ricorsivo per array multidimensionali sconosciuta profondità: Quando il numero di livelli in un array sono sconosciute, ricorsione è una tecnica logica. Il codice seguente elaborerà ogni sottoarray, rimuovendo i valori di lunghezza zero e qualsiasi sottoarray vuoto mentre procede. Here is a demo of this code with a few sample inputs.

$array=[ 
    ['Name'=>'','Array'=>['Keep'=>'Keep','Drop'=>['Drop2'=>'']],'EmailAddress'=>'','Pets'=>0,'Children'=>null], 
    ['Name'=>'','EmailAddress'=>'','FavoriteNumber'=>'0'] 
]; 

function removeEmptyValuesAndSubarrays($array){ 
    foreach($array as $k=>&$v){ 
     if(is_array($v)){ 
      $v=removeEmptyValuesAndSubarrays($v); // filter subarray and update array 
      if(!sizeof($v)){ // check array count 
       unset($array[$k]); 
      } 
     }elseif(!strlen($v)){ // this will handle (int) type values correctly 
      unset($array[$k]); 
     } 
    } 
    return $array; 
} 

var_export(removeEmptyValuesAndSubarrays($array)); 

uscita:

array (
    0 => 
    array (
    'Array' => 
    array (
     'Keep' => 'Keep', 
    ), 
    'Pets' => 0, 
), 
    1 => 
    array (
    'FavoriteNumber' => '0', 
), 
) 

Se qualcuno scopre una serie di input che spezza il metodo ricorsivo, si prega di postare (nella sua forma più semplice), come un commento e io aggiornare la mia risposta.

Problemi correlati