W3docs

Utilizzo di array_udiff_uassoc in PHP

Scopri come usare la funzione PHP array_udiff_uassoc per calcolare la differenza tra due o più array con funzioni di confronto personalizzate.

array_udiff_uassoc() calcola la differenza tra due o più array verificando sia le chiavi che i valori — e ti permette di decidere come vengono confrontati entrambi fornendo due callback personalizzate. Un elemento del primo array viene mantenuto nel risultato solo se nessun altro array contiene un elemento che corrisponde ad esso sia per chiave che per valore, secondo le tue callback.

Questa pagina spiega esattamente come interagiscono le due callback (la parte che la maggior parte della documentazione di riferimento sorvola), percorre un esempio eseguibile e mostra quando questa funzione è lo strumento giusto rispetto alle sue versioni più semplici.

Cos'è array_udiff_uassoc?

array_udiff_uassoc() restituisce le voci di $array1 che non sono presenti in nessuno degli altri array. A differenza di array_diff(), che confronta solo i valori con casting a string, questa variante verifica chiavi e valori insieme e delega entrambi i confronti a funzioni fornite dall'utente — è questo il significato delle due u nel nome (udiff = confronto valori utente, uassoc = confronto chiavi utente).

La firma è:

Sintassi della funzione 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

Le due callback sono sempre gli ultimi due argomenti, in questo ordine: il confronto dei valori per primo, il confronto delle chiavi per secondo. Tutto ciò che le precede è un array. Il risultato è un nuovo array con le voci di $array1 che superano il confronto, con le loro chiavi originali preservate.

Come funziona effettivamente la corrispondenza. Per ogni voce in $array1, PHP cerca negli altri array una voce la cui chiave sia "uguale" secondo $key_compare_func e il cui valore sia "uguale" secondo $value_compare_func. Se tale corrispondenza esiste in qualsiasi altro array, la voce viene eliminata; altrimenti viene mantenuta. Una voce viene rimossa solo quando entrambi i confronti riportano uguaglianza.

Comprendere le funzioni di confronto

Ogni callback riceve due argomenti e deve restituire un intero, esattamente come un comparatore di ordinamento:

  • Restituisce 0 quando i due elementi sono considerati uguali.
  • Restituisce un intero positivo quando il primo è "maggiore".
  • Restituisce un intero negativo quando il primo è "minore".

PHP si preoccupa solo se il valore restituito è 0 (uguale) o meno, ma è richiesto un risultato a tre vie coerente perché la funzione ordina internamente. L'operatore spaceship <=> è il modo più semplice per scriverne uno:

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

Poiché sei tu a definire entrambi i confronti, puoi fare cose che le funzioni diff integrate non possono — ad esempio, trattare le chiavi senza distinzione tra maiuscole e minuscole, o confrontare oggetti per una singola proprietà.

Esempio: utilizzo di base

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

?>

Qui compare_values e compare_keys sono semplici comparatori a tre vie. La chiamata calcola la differenza tra $array1 e $array2 e $array3, mantenendo solo le voci la cui chiave e valore non corrispondono da nessun'altra parte. L'output è:

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

Analizziamo perché ogni voce sopravvive o viene eliminata:

  • a => apple — eliminato: $array2 (e $array3) ha la stessa chiave a e lo stesso valore apple.
  • b => bananamantenuto: gli altri array usano la chiave b, ma i loro valori sono game / door, non banana. I valori differiscono, quindi non c'è corrispondenza.
  • c => cherry — eliminato: corrisposto da entrambi gli altri array.
  • d => durianmantenuto: $array3 contiene il valore durian, ma sotto la chiave g, non d. Le chiavi differiscono, quindi non c'è corrispondenza.

Quest'ultimo caso è il punto centrale della funzione: anche se il valore durian esiste altrove, la chiave non corrisponde, quindi la voce rimane. Una diff solo per valori come array_udiff() l'avrebbe rimossa.

Esempio: chiavi senza distinzione maiuscole/minuscole

Poiché il confronto delle chiavi è definito da te, puoi ignorare le maiuscole nelle chiavi pur confrontando i valori in modo rigoroso:

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

Output:

Array
(
    [z] => 30
)

x => 10 e y => 20 vengono rimossi (current ha lo stesso valore sotto una chiave che corrisponde senza distinzione tra maiuscole e minuscole), mentre z => 30 sopravvive perché current ha z => 99 — la chiave corrisponde ma il valore 99 !== 30.

Quando usarla (e cosa usare invece)

Ricorri a array_udiff_uassoc() solo quando hai bisogno di logica personalizzata per entrambe le chiavi e i valori. Se hai bisogno di meno, una funzione più semplice è più veloce da leggere e scrivere:

Hai bisogno di controllare…Usa
Solo i valori (callback), chiavi ignoratearray_udiff()
Valori (callback) + chiavi con ===array_udiff_assoc()
Chiavi (callback) + valori con ===array_diff_uassoc()
Nessuno — diff semplice per valoriarray_diff()

Errori comuni

  • Ordine degli argomenti. Le callback sono gli ultimi due argomenti, con il confronto valori per primo. Passarle nell'ordine sbagliato produce risultati errati senza generare errori.
  • Almeno due array. Devi passare $array1, almeno un altro array, e poi entrambe le callback — un minimo di cinque argomenti.
  • Restituisci un int, non un bool. Restituire true/false da un comparatore funziona per caso (vengono castati a 1/0) ma compromette l'ordinamento. Usa <=> o un esplicito -1/0/1.
  • Le chiavi sono preservate. Il risultato mantiene le chiavi originali di $array1; non viene reindicizzato.

Se le callback sono nuove per te, vedi PHP Callback Functions, e per un ripasso sugli array in generale, PHP Arrays.

Conclusione

array_udiff_uassoc() è la più flessibile delle funzioni di differenza tra array di PHP: confronta le voci sia per chiave che per valore, e delega entrambi i confronti alle tue callback personalizzate. Una voce del primo array sopravvive solo quando nessun altro array la corrisponde su entrambe le dimensioni. Usala quando le regole di confronto integrate (===, casting a string) non sono sufficienti — ad esempio chiavi senza distinzione tra maiuscole e minuscole, valori con supporto locale, o confronto di oggetti per un campo — e ricadi su una variante array_diff* più semplice quando non hai bisogno di tanto controllo.

Esercizio

Pratica
Qual è la funzionalità della funzione array_udiff_uassoc in PHP?
Qual è la funzionalità della funzione array_udiff_uassoc in PHP?
Was this page helpful?