W3docs

Usando array_udiff_uassoc em PHP

Aprenda a usar a função PHP array_udiff_uassoc para calcular a diferença entre dois ou mais arrays com funções de comparação definidas pelo usuário.

array_udiff_uassoc() calcula a diferença entre dois ou mais arrays verificando tanto as chaves quanto os valores — e permite que você decida como ambos são comparados fornecendo dois callbacks próprios. Um elemento do primeiro array é mantido no resultado somente se nenhum outro array contiver um elemento que corresponda a ele tanto na chave quanto no valor, de acordo com seus callbacks.

Esta página explica exatamente como os dois callbacks interagem (a parte que a maioria das referências ignora), percorre um exemplo executável e mostra quando esta função é a ferramenta certa em comparação com suas variantes mais simples.

O que é array_udiff_uassoc?

array_udiff_uassoc() retorna as entradas de $array1 que não estão presentes em nenhum dos outros arrays. Ao contrário de array_diff(), que compara valores apenas com conversão para string, esta variante verifica chaves e valores juntos e delega ambas as comparações a funções fornecidas pelo usuário — é isso que os dois us no nome significam (udiff = comparação de valor pelo usuário, uassoc = comparação de chave pelo usuário).

A assinatura é:

Sintaxe da função 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

Os dois callbacks são sempre os dois últimos argumentos, nesta ordem: comparação de valor primeiro, comparação de chave segundo. Tudo antes deles é um array. O resultado é um novo array com as entradas de $array1 que sobrevivem à comparação, com suas chaves originais preservadas.

Como o matching realmente funciona. Para cada entrada em $array1, o PHP percorre os outros arrays em busca de uma entrada cuja chave seja "igual" conforme $key_compare_func e cujo valor seja "igual" conforme $value_compare_func. Se tal correspondência existir em qualquer outro array, a entrada é descartada; caso contrário, é mantida. Uma entrada só é removida quando ambas as comparações indicam igualdade.

Entendendo as funções de comparação

Cada callback recebe dois argumentos e deve retornar um inteiro, exatamente como um comparador de ordenação:

  • Retorne 0 quando os dois itens forem considerados iguais.
  • Retorne um inteiro positivo quando o primeiro for "maior".
  • Retorne um inteiro negativo quando o primeiro for "menor".

O PHP só se importa se o valor de retorno é 0 (igual) ou não, mas um resultado de três vias consistente é necessário porque a função ordena internamente. O operador nave espacial <=> é a maneira mais fácil de escrever um:

$value_compare_func = fn($a, $b) => $a <=> $b;   // strict ordering
$key_compare_func   = fn($a, $b) => strcasecmp((string) $a, (string) $b); // case-insensitive keys

Como você define ambas as comparações, pode fazer coisas que as funções de diff integradas não conseguem — por exemplo, tratar chaves sem distinção de maiúsculas e minúsculas, ou comparar objetos por uma única propriedade.

Exemplo: 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);

?>

Aqui compare_values e compare_keys são comparadores simples de três vias. A chamada faz o diff de $array1 contra $array2 e $array3, mantendo apenas as entradas cuja chave e valor não correspondam a nada nos outros arrays. A saída é:

Array
(
    [b] => banana
    [d] => durian
)

Veja por que cada entrada sobrevive ou é descartada:

  • a => apple — descartada: $array2 (e $array3) tem a mesma chave a e o mesmo valor apple.
  • b => bananamantida: os outros arrays usam a chave b, mas seus valores são game / door, não banana. Os valores diferem, então não há correspondência.
  • c => cherry — descartada: correspondida por ambos os outros arrays.
  • d => durianmantida: $array3 contém o valor durian, mas sob a chave g, não d. As chaves diferem, então não há correspondência.

Esse último caso é o ponto central da função: mesmo que o valor durian exista em outro lugar, a chave não corresponde, então a entrada permanece. Um diff apenas por valor como array_udiff() a teria removido.

Exemplo: chaves sem distinção de maiúsculas e minúsculas

Como a comparação de chaves é sua para definir, você pode ignorar a capitalização das chaves enquanto ainda compara valores estritamente:

<?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);

Saída:

Array
(
    [z] => 30
)

x => 10 e y => 20 são removidos (current tem o mesmo valor sob uma chave que corresponde sem distinção de maiúsculas e minúsculas), enquanto z => 30 sobrevive porque current tem z => 99 — a chave corresponde, mas o valor 99 !== 30.

Quando usá-la (e o que usar no lugar)

Use array_udiff_uassoc() apenas quando precisar de lógica personalizada para ambas as chaves e os valores. Se precisar de menos, uma variante mais simples é mais rápida de ler e escrever:

O que você precisa controlar…Use
Apenas valores (callback), chaves ignoradasarray_udiff()
Valores (callback) + chaves com ===array_udiff_assoc()
Chaves (callback) + valores com ===array_diff_uassoc()
Nenhum — diff simples por valorarray_diff()

Armadilhas comuns

  • Ordem dos argumentos. Os callbacks são os dois últimos argumentos, o de comparação de valor primeiro. Passá-los na ordem errada produz resultados incorretos silenciosamente, sem gerar erro.
  • Pelo menos dois arrays. Você deve passar $array1, pelo menos um outro array e ambos os callbacks — no mínimo cinco argumentos.
  • Retorne um int, não um bool. Retornar true/false de um comparador funciona por acidente (eles são convertidos para 1/0), mas quebra a ordenação. Use <=> ou um -1/0/1 explícito.
  • Chaves são preservadas. O resultado mantém as chaves originais de $array1; não é re-indexado.

Se callbacks são novidade para você, veja PHP Callback Functions, e para uma revisão sobre arrays em geral, PHP Arrays.

Conclusão

array_udiff_uassoc() é a mais flexível das funções de diferença de array do PHP: compara entradas em chave e valor, e delega ambas as comparações aos seus próprios callbacks. Uma entrada do primeiro array sobrevive apenas quando nenhum outro array a corresponde em ambas as dimensões. Use-a quando as regras de comparação integradas (===, conversão para string) não forem suficientes — por exemplo, chaves sem distinção de maiúsculas e minúsculas, valores sensíveis ao locale, ou comparação de objetos por um campo — e volte a uma variante mais simples de array_diff* quando não precisar de tanto controle.

Prática

Prática
Qual é a funcionalidade da função array_udiff_uassoc em PHP?
Qual é a funcionalidade da função array_udiff_uassoc em PHP?
Was this page helpful?