2011-01-07 15 views
6

Digamos que yo quiero hacer esto:PHP Pregunta: ¿cómo array_intersect_assoc() de forma recursiva

 
$a = array_intersect_assoc(
array(
    'key1' => array(
    'key2' => 'value2' 
), 
    'key3' => 'value3', 
    'key4' => 'value4' 
), 

array(
    'key1' => array(
    'key2' => 'some value not in the first parameter' 
), 
    'key3' => 'another value' 
) 
); 

var_dump($a); 

El resultado impreso es:

 
array 
    'key1' => 
    array 
     'key2' => string 'value2' (length=6) 

Está claro que los valores asociados con 'clave2' en tanto las matrices no son iguales, sin embargo, array_intersect_assoc() aún devuelve 'key2' => 'value2' como el valor intersecado.

¿Es este el comportamiento esperado de array_intersect_assoc()?

Gracias!

+3

Eso es bastante increíble! Especialmente desde 'array ('key2' => 'value2') == array ('key2' => 'algún valor no en el primer parámetro') === falso', mientras que' array ('key2' => 'value2 ') == array (' key2 '=>' value2 ') === true'. Creo que hablo por muchas personas aquí cuando digo: eh. –

Respuesta

6

Sí, es el comportamiento esperado, porque la comparación se realiza mediante representaciones de cadenas, y la función no recurre hacia abajo matrices anidadas. Desde el manual:

Los dos valores desde el valor clave => pares se consideran iguales sólo si (string) $ elem1 === (string) $ elem2. En otras palabras, se ejecuta una verificación de tipo estricta para que la representación de cadena sea la misma.

Si se trató de cruzarse con una matriz con 'key1' => 'Array', se obtendría el mismo resultado porque la representación de cadena de una matriz es siempre 'Array'.

One of the user-contributed notes, por nleippe, contiene una implementación recursiva que parece prometedor (he modificado la tercera línea de hacer la comparación de cadenas de cualesquiera valores no-array):

function array_intersect_assoc_recursive(&$arr1, &$arr2) { 
    if (!is_array($arr1) || !is_array($arr2)) { 
//  return $arr1 == $arr2; // Original line 
     return (string) $arr1 == (string) $arr2; 
    } 
    $commonkeys = array_intersect(array_keys($arr1), array_keys($arr2)); 
    $ret = array(); 
    foreach ($commonkeys as $key) { 
     $ret[$key] =& array_intersect_assoc_recursive($arr1[$key], $arr2[$key]); 
    } 
    return $ret; 
} 
+0

¡Gracias! Todo tiene sentido ahora :) – garyc40

+0

He actualizado la última implementación con una compatibilidad hacia atrás más convencional http://www.php.net/manual/en/function.array-intersect-assoc.php#111707. – Gajus

+0

La función anterior funcionó para mí, pero tuve que eliminar el signo ampersand para evitar una advertencia estricta en PHP 5.6.30 en Ubuntu 16.04 debido al uso de la referencia en la asignación en el bucle foreach, es decir, cambiar '$ ret [$ key] = & array_intersect_assoc_recursive ($ arr1 [$ key], $ arr2 [$ key]); 'to' $ ret [$ key] = array_intersect_assoc_recursive ($ arr1 [$ key], $ arr2 [$ key]); ' – KolaB

Cuestiones relacionadas