2010-02-06 11 views
10

Esiste un approccio per la ricorsività di matrici, allo stesso modo della funzione PHP array_merge_recursive(), eccetto che le chiavi integer sono trattate come le chiavi di stringa?Il comportamento array_merge_recursive di PHP su chiavi intere

(E 'importante per il processo che le chiavi rimangono parse-grado come numeri interi.)

Ad esempio:

$a = array(
    'a' => array(1) 
); 
$b = array(
    'a' => array(2, 3) 
); 
var_dump(array_merge_recursive($a, $b)); 

fonderà i sul tasto e l'output "a", come previsto, il seguente:

array(1) { 
    ["a"] => array(3) { 
     [0] => int(1) 
     [1] => int(2) 
     [2] => int(3) 
    } 
} 

Tuttavia, quando si utilizza interi per le chiavi (anche quando come una stringa):

$a = array(
    '123' => array(1) 
); 
$b = array(
    '123' => array(2, 3) 
); 
var_dump(array_merge_recursive($a, $b)); 

array_merge_recursive() restituirà:

array(2) { 
    [0] => array(3) { 
     [0] => int(1) 
    } 
    [1] => array(2) { 
     [0] => int(2) 
     [1] => int(3) 
    } 
} 

Al posto del tanto desiderato:

array(1) { 
    ["123"] => array(3) { 
     [0] => int(1) 
     [1] => int(2) 
     [2] => int(3) 
    } 
} 

Pensieri?

risposta

2

si può precedere le chiavi dell'array con una breve stringa:

function addPrefix($a) { 
    return '_' . $a; 
} 
# transform keys 
$array1 = array_combine(array_map('addPrefix', array_keys($array1)), $array1); 
$array2 = array_combine(array_map('addPrefix', array_keys($array2)), $array2); 
# call array_combine 
$array = array_merge_recursive($array1, $array2); 
# reverse previous operation 
function stripPrefix($a) { 
    return substr($a, 1); 
} 
$array = array_combine(array_map('stripPrefix', array_keys($array)), $array)  
+1

Mentre questo è corretto sembra troppo artificioso. Perché non un ciclo regolare, invece? – Ezequiel

3

sto utilizzando l'idea di soulmerge di convertire le chiavi con l'aggiunta di una stringa. La mia nuova funzione può gestire solo 2 parametri, tuttavia, ma era il caso che avevi, quindi è quello che sono andato con. Dare un'occhiata.

// Adds a _ to top level keys of an array 
function prefixer($array) { 
    $out = array(); 
    foreach($array as $k => $v) { 
     $out['_' . $k] = $v; 
    } 
    return $out; 
} 
// Remove first character from all keys of an array 
function unprefixer($array) { 
    $out = array(); 
    foreach($array as $k => $v) { 
     $newkey = substr($k,1); 
     $out[$newkey] = $v; 
    } 
    return $out; 
} 
// Combine 2 arrays and preserve the keys 
function array_merge_recursive_improved($a, $b) { 
    $a = prefixer($a); 
    $b = prefixer($b); 
    $out = unprefixer(array_merge_recursive($a, $b)); 
    return $out; 
} 

E come sono i dati di esempio?

// some sample data  
$a = array(
    '123' => array(1) 
); 
$b = array(
    '123' => array(2, 3) 
); 

// what do the results say:  
print_r($a); 
// Array 
// (
//  [123] => Array 
//   (
//    [0] => 1 
//  ) 
// 
//) 

print_r($b); 
// Array 
// (
//  [123] => Array 
//   (
//    [0] => 2 
//    [1] => 3 
//  ) 
// 
//) 

E cerchiamo di provarli:

print_r(array_merge_recursive($a, $b)); 
// Array 
// (
//  [0] => Array 
//   (
//    [0] => 1 
//  ) 
// 
//  [1] => Array 
//   (
//    [0] => 2 
//    [1] => 3 
//  ) 
// 
//) 

print_r(array_merge_recursive_improved($a, $b)); 
// Array 
// (
//  [123] => Array 
//   (
//    [0] => 1 
//    [1] => 2 
//    [2] => 3 
//  ) 
// 
//) 
+1

Le funzioni 'prefixer' e' unprefixer' devono verificare se il valore è un array! Ad esempio, nel 'prefixer', è necessario disporre di' if (is_array ($ v)) \t \t { \t \t \t $ out [ '_'. $ k] = prefisso ($ v); \t \t} \t \t altro \t \t { \t \t \t $ out [ '_'.$ k] = $ v; \t \t} 'all'interno del ciclo. Altrimenti funziona alla grande! – Link14

0

Se si desidera che i tasti da trattare come stringhe solo rendono stringhe aggiunta di un prefisso quando si riempie, invece di riempirlo con i numeri e quindi riempire un altro array solo per ordinarlo.

0

Questa funzione di unione merge ricorsiva non rinumifica le chiavi integer e aggiunge nuovi valori a quelli esistenti OPPURE aggiunge una nuova coppia [chiave => valore] se la coppia non esiste. Suppongo ed esisto sicuro, che questa funzione è ciò di cui hai bisogno.

function array_merge_recursive_adv(array &$array1, $array2) { 
     if(!empty($array2) && is_array($array2)) 
      foreach ($array2 as $key => $value) { 
        if(array_key_exists($key,$array1)) { 
         if(is_array($value)){ 
          array_merge_recursive_adv($array1[$key], $value); 
         } else { 
          if(!empty($array1[$key])) { 
           if(is_array($array1[$key])){ 
            array_push($array1[$key], $value); 
           } else { 
            $array1[$key] = [$array1[$key]]; 
            $array1[$key][] = $value; 
           } 
          } else if(empty($array1[$key])) { 
           $array1[$key] = $value; 
          } 
         } 
        } else { 
         $array1[$key] = $value; 
        } 
      } 
      return $array1; 
    } 
Problemi correlati