2009-11-10 22 views
9

Ho il seguente array che ho bisogno di ricorrere in loop in modo ricorsivo e rimuovere qualsiasi array figlio che abbia la chiave "campi". Ho provato il filtro di array, ma ho difficoltà a far funzionare nulla.PHP Annulla ricorsivamente le chiavi dell'array se corrisponde a

$myarray = array(
    'Item' => array(
     'fields' => array('id', 'name'), 
     'Part' => array(
      'fields' => array('part_number', 'part_name') 
     ) 
    ), 
    'Owner' => array(
     'fields' => array('id', 'name', 'active'), 
     'Company' => array(
      'fields' => array('id', 'name',), 
      'Locations' => array(
       'fields' => array('id', 'name', 'address', 'zip'), 
       'State' => array(
        'fields' => array('id', 'name') 
       ) 
      ) 
     ) 
    )  
); 

Questo è quanto ho bisogno del risultato a guardare come:

$myarray = array(
    'Item' => array(
     'Part' => array(
     ) 
    ), 
    'Owner' => array(
     'Company' => array(
      'Locations' => array(
       'State' => array(
       ) 
      ) 
     ) 
    )  
); 
+0

Quale valore si "parte" avere dopo l'azione di rimozione? – powtac

+0

Ho solo bisogno di disinserire i "campi" e lasciare la parte come 'array()' – SonnyBurnette

risposta

28

Se si vuole operare in modo ricorsivo, è necessario passare la matrice come reference, altrimenti si fa un sacco di inutilmente la copia:

function recursive_unset(&$array, $unwanted_key) { 
    unset($array[$unwanted_key]); 
    foreach ($array as &$value) { 
     if (is_array($value)) { 
      recursive_unset($value, $unwanted_key); 
     } 
    } 
} 
+0

cool, ho sicuramente bisogno di provare questo! –

+0

Non sono sicuro che sia corretto. Dal manuale php: Se una variabile che è PASSATO DA RIFERIMENTO è non impostata() all'interno di una funzione, solo la variabile locale viene distrutta. La variabile nell'ambiente chiamante manterrà lo stesso valore di prima che unset() fosse chiamato. http://php.net/manual/en/function.unset.php – Gerbus

+0

@Gerbus: tale istruzione si applica solo alla variabile stessa, non ai suoi * valori * (o chiavi-array in questo caso). La modifica dell'array non invalida il riferimento all'array passato. In altre parole: si sarebbe corretto se il codice contenesse 'unset ($ array);', ma questo codice annulla la chiave dell'array. – soulmerge

0

dare a questa funzione di un colpo. Rimuoverà le chiavi con 'campi' e lascerà il resto dell'array.

function unsetFields($myarray) { 
    if (isset($myarray['fields'])) 
     unset($myarray['fields']); 
    foreach ($myarray as $key => $value) 
     $myarray[$key] = unsetFields($value); 
    return $myarray; 
} 
1

Il mio suggerimento:

function removeKey(&$array, $key) 
{ 
    if (is_array($array)) 
    { 
     if (isset($array[$key])) 
     { 
      unset($array[$key]); 
     } 
     if (count($array) > 0) 
     { 
      foreach ($array as $k => $arr) 
      { 
       removeKey($array[$k], $key); 
      } 
     } 
    } 
} 

removeKey($myarray, 'Part'); 
+0

isset non è il migliore in questo caso, dovrebbe usare array_key_exists null]; var_dump (isset ($ a ['chiave'])); // restituisce false var_dump (array_key_exists ('chiave', $ a)); // restituisce true –

-1

Cammina ricorsivamente l'array (per riferimento) e disattiva i tasti corrispondenti.

clear_fields($myarray); 
print_r($myarray); 

function clear_fields(&$parent) { 
    unset($parent['fields']); 
    foreach ($parent as $k => &$v) { 
    if (is_array($v)) { 
     clear_fields($v); 
    } 
    } 
} 
1
function sanitize($arr) { 
    if (is_array($arr)) { 
     $out = array(); 
     foreach ($arr as $key => $val) { 
      if ($key != 'fields') { 
       $out[$key] = sanitize($val); 
      } 
     } 
    } else { 
     return $arr; 
    } 
    return $out; 
} 

$myarray = sanitize($myarray); 

Risultato:

array (
    'Item' => 
    array (
    'Part' => 
    array (
    ), 
), 
    'Owner' => 
    array (
    'Company' => 
    array (
     'Locations' => 
     array (
     'State' => 
     array (
     ), 
    ), 
    ), 
), 
) 
5

desideri array_walk

function remove_key(&$a) { 
    if(is_array($a)) { 
     unset($a['fields']); 
     array_walk($a, __FUNCTION__); 
    } 
} 
remove_key($myarray); 
+1

Un buon uso di lambda + costante locale, funziona in PHP 5.3+ – philwinkle

+3

Non dice array_walk che se disattivi un elemento che "[comportamento di questa funzione è indefinito e imprevedibile] (http: // php .net/manuale/it/function.array-walk.php)”? – greatwitenorth

+0

@greatwitenorth, lo dice. Questo potrebbe funzionare, ma probabilmente è meglio evitarlo tristemente. – Aaron

2
function recursive_unset(&$array, $unwanted_key) { 

    if (!is_array($array) || empty($unwanted_key)) 
     return false; 

    unset($array[$unwanted_key]); 

    foreach ($array as &$value) { 
     if (is_array($value)) { 
      recursive_unset($value, $unwanted_key); 
     } 
    } 
} 
0
function removeRecursive($haystack,$needle){ 
    if(is_array($haystack)) { 
     unset($haystack[$needle]); 
     foreach ($haystack as $k=>$value) { 
      $haystack[$k] = removeRecursive($value,$needle); 
     } 
    } 
    return $haystack; 
} 

$new = removeRecursive($old,'key'); 
-1

avevo bisogno di avere un po 'più granularità in array disinserimento e mi si avvicinò spirito h questo - con la valutazione del male e altri trucchi sporchi.

$post = array(); //some huge array 

function array_unset(&$arr,$path){ 
    $str = 'unset($arr[\''.implode('\'][\'',explode('/', $path)).'\']);'; 
    eval($str); 
} 

$junk = array(); 
$junk[] = 'property_meta/_edit_lock'; 
$junk[] = 'property_terms/post_tag'; 
$junk[] = 'property_terms/property-type/0/term_id'; 
foreach($junk as $path){ 
    array_unset($post,$path); 
} 

// unset($arr['property_meta']['_edit_lock']); 
// unset($arr['property_terms']['post_tag']); 
// unset($arr['property_terms']['property-type']['0']['term_id']); 
+0

Cura di commentare il voto negativo? –

0

Codice:

$sweet = array('a' => 'apple', 'b' => 'banana'); 
$fruits = array('sweet' => $sweet, 'sour' => $sweet); 

function recursive_array_except(&$array, $except) 
{ 
    foreach($array as $key => $value){ 
    if(in_array($key, $except, true)){ 
     unset($array[$key]); 
    }else{ 
     if(is_array($value)){ 
     recursive_array_except($array[$key], $except); 
     } 
    } 
    } 
    return; 
} 

recursive_array_except($fruits, array('a')); 
print_r($fruits); 

ingresso:

Array 
(
    [sweet] => Array 
     (
      [a] => apple 
      [b] => banana 
     ) 

    [sour] => Array 
     (
      [a] => apple 
      [b] => banana 
     ) 

) 

uscita:

Array 
(
    [sweet] => Array 
     (
      [b] => banana 
     ) 

    [sour] => Array 
     (
      [b] => banana 
     ) 

) 
Problemi correlati