2010-02-06 11 views
10

¿Hay un enfoque para combinar matrices recursivamente, de la misma manera que la función array_merge_recursive() de PHP, excepto que las claves enteras se tratan igual que las claves de cadena?Comportamiento array_merge_recursive de PHP en llaves enteras

(Es importante para el proceso que las claves de permanecer análisis sintáctico-poder como enteros.)

Por ejemplo:

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

fusionará los de la llave y la salida "a", como se esperaba, lo siguiente:

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

Sin embargo, cuando se utiliza enteros de teclas (incluso cuando como una cadena):

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

array_merge_recursive() devolverá:

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

En lugar de la tan deseada:

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

Pensamientos?

Respuesta

2

se puede prefijar las claves de matriz con una cadena corta:

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

Si bien esto es correcto, se siente demasiado artificial. ¿Por qué no un bucle regular en su lugar? – Ezequiel

3

estoy usando la idea de soulmerge de convertir las claves mediante la adición de una cadena. Sin embargo, mi nueva función solo puede manejar 2 parámetros, pero ese era el caso que tenías, así que eso es lo que hice. Echar un vistazo.

// 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; 
} 

¿Y cómo son los datos de muestra?

// 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 
//  ) 
// 
//) 

Y vamos a intentar sacarlos:

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

¡Las funciones 'prefixer' y' unprefixer' necesitan verificar si el valor es una matriz! Por ejemplo, en el 'prefijo ', debe tener' if (is_array ($ v)) \t \t { \t \t \t $ out [' _ '. $ k] = prefijo ($ v); \t \t} \t \t demás \t \t { \t \t \t $ cabo [ '_'.$ k] = $ v; \t \t} 'dentro del ciclo. De lo contrario, está funcionando bien! – Link14

0

Si desea que las claves para ser tratados como cadenas sólo lo hacen encadena la adición de un prefijo cuando lo llenas, en lugar de llenarlo con los números y luego rellene otra matriz solo para ordenarla.

0

Esta función de combinación de matriz recursiva no renumera las claves enteras y agrega nuevos valores a las existentes O agrega un nuevo par [clave => valor] si el par no existe. Supongo y estoy seguro de que esta función es lo que necesitas.

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; 
    }