Comprender la función array_udiff() de PHP
Aprende cómo array_udiff() de PHP compara arrays con un callback personalizado y devuelve los valores exclusivos del primer array. Ejemplos con números y objetos.
array_udiff() calcula la diferencia entre arrays comparando sus valores con una función callback que tú proporcionas. Devuelve los valores presentes en el primer array que no se encuentran en ninguno de los demás arrays. La "u" en el nombre significa definida por el usuario — a diferencia de array_diff(), que compara valores como string, array_udiff() te permite decidir exactamente cuándo dos valores se consideran "iguales".
Esta página cubre la sintaxis de la función, cómo funciona el callback, ejemplos ejecutables con números y objetos, y los errores comunes a tener en cuenta.
¿Cuándo usarías array_udiff()?
Recurre a array_udiff() siempre que la comparación predeterminada de array_diff() sea demasiado básica:
- Objetos.
array_diff()convierte cada valor a string. Los objetos sin un método__toString()no pueden compararse de esa manera, por lo que necesitas un callback que inspeccione una propiedad en su lugar. - Igualdad personalizada. Quieres una comparación sin distinción de mayúsculas, una comparación por un solo campo, o una comparación numérica basada en tolerancia.
- Datos mixtos o normalizados. Quieres tratar
"5",5y5.0como el mismo valor, o comparar números de punto flotante con redondeo.
Si solo necesitas una comparación simple de string, prefiere el más sencillo array_diff().
Cómo funciona array_udiff()
La función acepta dos o más arrays, siendo el último argumento el callback de comparación. Devuelve un array con los valores del primer array que el callback no encuentra iguales a ningún valor de los arrays posteriores. Las claves y el orden del primer array se conservan.
Sintaxis
array_udiff(array $array1, array $array2, array ...$arrays, callable $value_compare_func): arrayarray $array1— el array cuyos valores se devuelven (el array "base").array $array2— un array con el que comparar.array ...$arrays— cualquier número de arrays adicionales con los que comparar.callable $value_compare_func— el callback de comparación. Siempre es el último argumento.
El callback de comparación
El callback recibe dos valores y debe devolver un entero:
- un número menor que 0 si el primer valor es "menor",
- 0 si los dos valores se consideran iguales,
- un número mayor que 0 si el primer valor es "mayor".
Devolver 0 es lo que marca dos valores como iguales, por lo que un valor en $array1 se excluye del resultado cuando el callback devuelve 0 al compararlo con algún valor de un array posterior. Los resultados < 0 / > 0 permiten a PHP ordenar los valores internamente para una comparación eficiente — obtenerlos correctamente importa, así que no devuelvas simplemente 0 o 1. El operador nave espacial (<=>) es la forma más fácil y correcta de producir este valor.
Ejemplo 1: comparar dos arrays de números
Este ejemplo usa una función con nombre como callback para encontrar los números que están en $array1 pero no en $array2:
<?php
function compare_numbers($a, $b) {
if ($a == $b) {
return 0;
} elseif ($a < $b) {
return -1;
} else {
return 1;
}
}
$array1 = [1, 2, 3, 4, 5];
$array2 = [2, 4, 6];
$result = array_udiff($array1, $array2, 'compare_numbers');
print_r($result);
?>compare_numbers() devuelve 0 cuando dos valores coinciden, por lo que los números coincidentes (2 y 4) son eliminados. El resultado conserva las claves originales de $array1:
Array
(
[0] => 1
[2] => 3
[4] => 5
)Todo el callback podría reemplazarse con una sola línea usando el operador nave espacial: fn($a, $b) => $a <=> $b.
Ejemplo 2: comparar arrays de objetos
Este es el caso que array_diff() no puede manejar. Aquí comparamos dos arrays de objetos Product por su id, devolviendo los productos que no están en la segunda lista:
<?php
class Product {
public function __construct(public int $id, public string $name) {}
}
$catalog = [
new Product(1, 'Keyboard'),
new Product(2, 'Mouse'),
new Product(3, 'Monitor'),
];
$discontinued = [
new Product(2, 'Mouse'),
];
$available = array_udiff(
$catalog,
$discontinued,
fn(Product $a, Product $b) => $a->id <=> $b->id
);
foreach ($available as $product) {
echo $product->id . ': ' . $product->name . PHP_EOL;
}
?>Esto imprime los productos cuyo id no está presente en $discontinued:
1: Keyboard
3: MonitorDado que el callback compara únicamente el id, los valores distintos en name son irrelevantes — la lógica de comparación es completamente tuya para definir.
Cosas a tener en cuenta
- El callback siempre es el último argumento, sin importar cuántos arrays pases.
array_udiff()compara valores. Para comparar tanto claves como valores, usaarray_udiff_assoc(); para comparar también las claves con un callback, usaarray_udiff_uassoc().- Devuelve un resultado adecuado de tres vías (negativo /
0/ positivo), no solo0o1. PHP depende del ordenamiento para comparar eficientemente, y un callback descuidado puede producir resultados incorrectos. - El resultado conserva las claves y el orden de
$array1. Llama aarray_values()si quieres un array reindexado. - Solo los valores del primer array pueden aparecer en el resultado — los valores exclusivos de los arrays posteriores nunca se devuelven.
Funciones relacionadas
array_diff()— la misma idea con comparación de string simple.array_udiff_assoc()— callback de valor más comparación de claves.array_uintersect()— el equivalente de intersección (valores encontrados en todos los arrays).- PHP Arrays y PHP Functions para los fundamentos.