W3docs

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", 5 e 5.0 come 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): array
  • array $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: Monitor

Poiché 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, usa array_udiff_assoc(); per confrontare anche le chiavi con una callback, usa array_udiff_uassoc().
  • Restituisci un risultato corretto a tre vie (negativo / 0 / positivo), non solo 0 o 1. 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. Chiama array_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

Esercizio

Pratica
Qual è lo scopo della funzione array_udiff() in PHP?
Qual è lo scopo della funzione array_udiff() in PHP?
Was this page helpful?