Uso de array_udiff_uassoc en PHP
Aprende a usar la función PHP array_udiff_uassoc para calcular la diferencia entre dos o más arrays con funciones de comparación definidas por el usuario.
array_udiff_uassoc() calcula la diferencia entre dos o más arrays verificando tanto las claves como los valores — y te permite decidir cómo se comparan ambos mediante dos callbacks propios. Un elemento del primer array se mantiene en el resultado solo si ningún otro array contiene un elemento que coincida en clave y valor, según tus callbacks.
Esta página explica con precisión cómo interactúan los dos callbacks (la parte que la mayoría de la documentación de referencia omite), recorre un ejemplo ejecutable y muestra cuándo esta función es la herramienta adecuada frente a sus variantes más simples.
¿Qué es array_udiff_uassoc?
array_udiff_uassoc() devuelve las entradas de $array1 que no están presentes en ninguno de los otros arrays. A diferencia de array_diff(), que compara valores únicamente mediante conversión a string, esta variante verifica claves y valores juntos y delega ambas comparaciones a funciones definidas por el usuario — eso es lo que significan las dos u en el nombre (udiff = comparación de valores por el usuario, uassoc = comparación de claves por el usuario).
La firma es:
Sintaxis de la función PHP array_udiff_uassoc
array_udiff_uassoc(
array $array1,
array $array2,
array ...$arrays, // one or more additional arrays
callable $value_compare_func,
callable $key_compare_func
): arrayLos dos callbacks son siempre los dos últimos argumentos, en este orden: comparación de valores primero, comparación de claves segundo. Todo lo anterior es un array. El resultado es un nuevo array con las entradas de $array1 que superan la comparación, conservando sus claves originales.
Cómo funciona el matching en la práctica. Para cada entrada de
$array1, PHP recorre los demás arrays buscando una entrada cuya clave sea "igual" según$key_compare_funcy cuyo valor sea "igual" según$value_compare_func. Si dicha coincidencia existe en cualquier otro array, la entrada se descarta; de lo contrario se conserva. Una entrada se elimina solo cuando ambas comparaciones reportan igualdad.
Comprensión de las funciones de comparación
Cada callback recibe dos argumentos y debe devolver un entero, exactamente como un comparador de ordenación:
- Devuelve
0cuando los dos elementos se consideran iguales. - Devuelve un entero positivo cuando el primero es "mayor".
- Devuelve un entero negativo cuando el primero es "menor".
PHP solo se preocupa de si el valor de retorno es 0 (igual) o no, pero se requiere un resultado consistente de tres vías porque la función ordena internamente. El operador spaceship <=> es la forma más sencilla de escribirlo:
$value_compare_func = fn($a, $b) => $a <=> $b; // strict ordering
$key_compare_func = fn($a, $b) => strcasecmp((string) $a, (string) $b); // case-insensitive keysDebido a que tú defines ambas comparaciones, puedes hacer cosas que las funciones de diferencia integradas no pueden — por ejemplo, tratar las claves sin distinción de mayúsculas y minúsculas, o comparar objetos por una sola propiedad.
Ejemplo: uso básico
<?php
function compare_values($a, $b) {
if ($a === $b) {
return 0;
}
return ($a > $b) ? 1 : -1;
}
function compare_keys($a, $b) {
if ($a === $b) {
return 0;
}
return ($a > $b) ? 1 : -1;
}
$array1 = array('a' => 'apple', 'b' => 'banana', 'c' => 'cherry', 'd' => 'durian');
$array2 = array('a' => 'apple', 'b' => 'game', 'c' => 'cherry');
$array3 = array('a' => 'apple', 'b' => 'door', 'c' => 'cherry', 'g' => 'durian');
$result = array_udiff_uassoc($array1, $array2, $array3, 'compare_values', 'compare_keys');
print_r($result);
?>Aquí compare_values y compare_keys son comparadores simples de tres vías. La llamada calcula la diferencia de $array1 respecto a $array2 y $array3, conservando solo las entradas cuya clave y valor no coincidan en ningún otro lugar. La salida es:
Array
(
[b] => banana
[d] => durian
)Analicemos por qué cada entrada se conserva o se descarta:
a => apple— descartado:$array2(y$array3) tiene la misma claveay el mismo valorapple.b => banana— conservado: los otros arrays usan la claveb, pero sus valores songame/door, nobanana. Los valores difieren, por lo que no hay coincidencia.c => cherry— descartado: coincide con ambos arrays restantes.d => durian— conservado:$array3contiene el valordurian, pero bajo la claveg, nod. Las claves difieren, por lo que no hay coincidencia.
Ese último caso es el propósito central de la función: aunque el valor durian existe en otro lugar, la clave no coincide, por lo que la entrada permanece. Una diferencia solo por valor como array_udiff() la habría eliminado.
Ejemplo: claves sin distinción de mayúsculas y minúsculas
Como la comparación de claves la defines tú, puedes ignorar la capitalización de las claves mientras comparas los valores de forma estricta:
<?php
$wanted = ['x' => 10, 'y' => 20, 'z' => 30];
$current = ['x' => 10, 'Y' => 20, 'z' => 99];
$result = array_udiff_uassoc(
$wanted,
$current,
fn($v1, $v2) => $v1 <=> $v2, // values: strict ordering
fn($k1, $k2) => strcasecmp((string) $k1, (string) $k2) // keys: case-insensitive
);
print_r($result);Salida:
Array
(
[z] => 30
)x => 10 y y => 20 se eliminan (current tiene el mismo valor bajo una clave que coincide sin distinción de mayúsculas y minúsculas), mientras que z => 30 sobrevive porque current tiene z => 99 — la clave coincide pero el valor 99 !== 30.
Cuándo usarla (y qué usar en su lugar)
Recurre a array_udiff_uassoc() solo cuando necesites lógica personalizada para ambos, las claves y los valores. Si necesitas menos, una variante más simple es más rápida de leer y escribir:
| Lo que necesitas controlar… | Usa |
|---|---|
| Solo valores (callback), claves ignoradas | array_udiff() |
Valores (callback) + claves con === | array_udiff_assoc() |
Claves (callback) + valores con === | array_diff_uassoc() |
| Ninguno — diferencia simple por valor | array_diff() |
Errores comunes
- Orden de los argumentos. Los callbacks son los dos últimos argumentos, la comparación de valores primero. Pasarlos en el orden incorrecto produce resultados incorrectos en silencio en lugar de un error.
- Al menos dos arrays. Debes pasar
$array1, al menos otro array y luego ambos callbacks — cinco argumentos como mínimo. - Devuelve un
int, no unbool. Devolvertrue/falsedesde un comparador funciona por accidente (se convierten a1/0) pero rompe el ordenamiento. Usa<=>o un-1/0/1explícito. - Las claves se preservan. El resultado conserva las claves originales de
$array1; no se reindexa.
Si los callbacks son nuevos para ti, consulta Funciones Callback de PHP, y para un repaso general sobre arrays, Arrays en PHP.
Conclusión
array_udiff_uassoc() es la más flexible de las funciones de diferencia de arrays de PHP: compara las entradas tanto por clave como por valor, y delega ambas comparaciones a tus propios callbacks. Una entrada del primer array sobrevive solo cuando ningún otro array la coincide en ambas dimensiones. Úsala cuando las reglas de comparación integradas (===, conversión a string) no sean suficientes — por ejemplo, claves sin distinción de mayúsculas y minúsculas, valores con reconocimiento de configuración regional, o comparación de objetos por un campo — y recurre a una variante más simple de array_diff* cuando no necesites tanto control.