Comprendere la funzione array_udiff() di PHP
Scopri come array_udiff() di PHP confronta array tramite una callback personalizzata e restituisce i valori presenti solo nel primo array. Esempi con numeri e object.
array_udiff() calcola la differenza tra array confrontando i loro valori tramite una funzione di callback fornita da te. Restituisce i valori presenti nel primo array che non si trovano in nessuno degli altri array. La "u" nel nome sta per user-defined (definita dall'utente) — a differenza di array_diff(), che confronta i valori come string, array_udiff() ti permette di decidere esattamente quando due valori sono considerati "uguali".
Questa pagina illustra la sintassi della funzione, il funzionamento della callback, esempi eseguibili con numeri e object, e le insidie più comuni da tenere a mente.
Quando usare array_udiff()?
Ricorri a array_udiff() ogni volta che il confronto predefinito di array_diff() è troppo approssimativo:
- Object.
array_diff()converte ogni valore in una string. Gli object privi di un metodo__toString()non possono essere confrontati in questo modo, quindi hai bisogno di una callback che esamini una proprietà. - Uguaglianza personalizzata. Vuoi un confronto case-insensitive, un confronto basato su un singolo campo, o un confronto numerico con tolleranza.
- Dati misti o normalizzati. Vuoi trattare
"5",5e5.0come lo stesso valore, oppure confrontare float con arrotondamento.
Se hai bisogno solo di un confronto tra string semplici, preferisci il più semplice array_diff().
Come funziona array_udiff()
La funzione accetta due o più array, con l'ultimo argomento che è la callback di confronto. Restituisce un array con i valori del primo array che la callback non trova uguali ad alcun valore negli array successivi. Le chiavi e l'ordine del primo array vengono preservati.
Sintassi
array_udiff(array $array1, array $array2, array ...$arrays, callable $value_compare_func): arrayarray $array1— l'array i cui valori vengono restituiti (l'array "base").array $array2— un array con cui confrontare.array ...$arrays— un numero qualsiasi di array aggiuntivi con cui confrontare.callable $value_compare_func— la callback di confronto. È sempre l'ultimo argomento.
La callback di confronto
La callback riceve due valori e deve restituire un intero:
- un numero minore di 0 se il primo valore è "più piccolo",
- 0 se i due valori sono considerati uguali,
- un numero maggiore di 0 se il primo valore è "più grande".
Restituire 0 è ciò che contrassegna due valori come uguali, quindi un valore in $array1 viene escluso dal risultato ogni volta che la callback restituisce 0 per esso rispetto a qualche valore in un array successivo. I risultati < 0 / > 0 permettono a PHP di ordinare i valori internamente per un confronto efficiente — è importante restituirli correttamente, quindi non restituire semplicemente 0 o 1. L'operatore spaceship (<=>) è il modo più semplice e corretto per produrre questo valore.
Esempio 1: confronto di due array di numeri
Questo esempio usa una funzione con nome come callback per trovare i numeri presenti in $array1 ma non in $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() restituisce 0 ogni volta che due valori corrispondono, quindi i numeri corrispondenti (2 e 4) vengono rimossi. Il risultato mantiene le chiavi originali di $array1:
Array
(
[0] => 1
[2] => 3
[4] => 5
)L'intera callback potrebbe essere sostituita con una riga singola usando l'operatore spaceship: fn($a, $b) => $a <=> $b.
Esempio 2: confronto di array di object
Questo è il caso che array_diff() non riesce a gestire. Qui confrontiamo due array di object Product tramite il loro id, restituendo i prodotti che non si trovano nel secondo elenco:
<?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;
}
?>Questo stampa i prodotti il cui id non è presente in $discontinued:
1: Keyboard
3: MonitorPoiché la callback confronta solo l'id, i valori diversi di name sono irrilevanti — la logica di confronto è interamente tua da definire.
Cose da tenere a mente
- La callback è sempre l'ultimo argomento, indipendentemente dal numero di array passati.
array_udiff()confronta i valori. Per confrontare sia le chiavi che i valori, usaarray_udiff_assoc(); per confrontare anche le chiavi con una callback, usaarray_udiff_uassoc().- Restituisci un risultato corretto a tre vie (negativo /
0/ positivo), non solo0o1. PHP si affida all'ordinamento per confrontare in modo efficiente, e una callback approssimativa può produrre risultati errati. - Il risultato preserva le chiavi e l'ordine di
$array1. Chiamaarray_values()se desideri un array re-indicizzato. - Nel risultato possono comparire solo valori del primo array — i valori univoci degli array successivi non vengono mai restituiti.
Funzioni correlate
array_diff()— la stessa logica con confronto tra string semplici.array_udiff_assoc()— callback sui valori più confronto delle chiavi.array_uintersect()— l'equivalente dell'intersezione (valori presenti in tutti gli array).- PHP Arrays e PHP Functions per i fondamentali.