W3docs

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
): array

Los 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_func y 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 0 cuando 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 keys

Debido a que 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 clave a y el mismo valor apple.
  • b => bananaconservado: los otros arrays usan la clave b, pero sus valores son game / door, no banana. Los valores difieren, por lo que no hay coincidencia.
  • c => cherry — descartado: coincide con ambos arrays restantes.
  • d => durianconservado: $array3 contiene el valor durian, pero bajo la clave g, no d. 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 ignoradasarray_udiff()
Valores (callback) + claves con ===array_udiff_assoc()
Claves (callback) + valores con ===array_diff_uassoc()
Ninguno — diferencia simple por valorarray_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 un bool. Devolver true/false desde un comparador funciona por accidente (se convierten a 1/0) pero rompe el ordenamiento. Usa <=> o un -1/0/1 explí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.

Práctica

Práctica
¿Cuál es la funcionalidad de la función array_udiff_uassoc en PHP?
¿Cuál es la funcionalidad de la función array_udiff_uassoc en PHP?
Was this page helpful?