2013-06-21 23 views
7

La funzione in_array può confrontare gli oggetti?PHP in_array oggetto di confronto?

Ad esempio, ho una matrice di oggetti e voglio aggiungerli distintamente a un altro array. E 'possibile verificare se un oggetto è già stato aggiunto in questo modo:

in_array($distinct, $object); 

oppure esiste un altro modo?

+0

Qual è la tua definizione di "distinto"? Se "distinto" è l'opposto dell'uguaglianza di riferimento, allora basta passare in 'true' come il terzo parametro lo farà. – Jon

+0

Quindi questo funzionerà con gli oggetti nell'array? – gorgi93

+1

Per alcune definizioni di "lavoro". Devi dare maggiori dettagli, la lettura della mente è difficile. – Jon

risposta

11

La funzione in_array non può confrontare gli oggetti.

È necessario creare coppie di valori-chiave univoche dai propri oggetti e solo confrontare tali chiavi quando si inserisce un nuovo oggetto nell'array finale.

Supponendo che ogni oggetto ha un unico id immobili, una possibile soluzione potrebbe essere:

$unique_objects = array(); 

// $data represents your object collection 
foreach ($data as $item) { 
    if (!array_key_exists($item->id, $unique_objects)) { 
     $unique_objects[$item->id] = $obj; 
    } 
} 
+0

Ha effettivamente funzionato ... XD – gorgi93

+0

lol, cosa? $ idem non è una variabile da nessuna parte, e nemmeno $ obj? Come è stato votato 13 volte? –

+0

Buon punto. Ho aggiornato la risposta per correggere l'errore '$ idem'. L'ipotesi con questo codice di esempio è che '$ obj' rappresenta semplicemente una variabile esistente che deve essere aggiunta in modo univoco alla matrice' $ unique_objects'. – ukliviu

9

È possibile utilizzare rigoroso confronto: ad esempio

in_array($object, $array, TRUE); 

Usage:

$a = new stdClass(); 
$a->x = 42; 

$b = new stdClass(); 
$b->y = 42; 

$c = new stdClass(); 
$c->x = 42; 

$array = array($a,$b); 

echo in_array($a, $array, true); // 1 
echo in_array($b, $array, true); // 1 
echo in_array($c, $array, true); // 
0

Se "STRICT" è "FALSE", il confronto viene effettuato convertendo in una stringa l'elem Ent. Quindi, se si sostituisce la funzione magica __toString, si dovrebbe essere disponibili per confrontare gli elementi degli oggetti.

1

Non so se è a causa di una versione più recente di PHP, ma nel mio progetto, utilizzando PHP 5.3.16 su Ubuntu 12.04, ha funzionato. Ha trovato l'oggetto ago nella mia matrice di oggetti. Ho anche ricontrollato caricando un oggetto diverso della stessa classe, e testandolo contro il contenuto dell'array che non conteneva quell'oggetto, e restituito in effetti falso.

Quindi sì, in_array può confrontare oggetti.

0

Mi è venuta in mente un'opzione un po 'diversa, penso più robusta.

function array_add_unique(&$array, $new, $test, $cb) { 
    if(is_array($array) && count($array)>0) { 
    for($i = 0; $i < count($array); $i++) { 
     if($array[$i][$test] == $new[$test]) { 
     $do = $cb($array[$i], $new); 
     if(is_bool($do) && $do) { $array[$i] = $new; } 
     else if(!is_bool($do)) { $array[$i] = $do; } 
     return; 
     } 
    } 
    } 
    array_push($array, $new); 
} 

Il vantaggio di questa soluzione è che include un callback definibile dall'utente per gestire le collisioni. Quando aggiungi oggetti unici, potresti voler preservare le proprietà sia del vecchio che del nuovo oggetto.

Il callback, che può essere una funzione anonima, riceve sia il nuovo oggetto che l'oggetto esistente in modo che l'utente possa disporre di un calcolo personalizzato. Restituire true per sostituire semplicemente l'oggetto esistente o restituire un nuovo oggetto (non bool) per sostituirlo.

Tuttavia, non conosco le prestazioni di questo su grandi set di dati.

0

Ci sono molti modi in cui puoi farlo come puoi vedere. Ho solo pensato di aggiungerne un altro. Non so perché, ma quando lavoro con gli array di oggetti mi piace usare le funzioni dell'array che usano i callback.

Se gli oggetti hanno alcun tipo di identificazione, che dovrebbero, se si vuole testare loro per la duplicazione, la proceda in questo modo:

$found = array_filter($uniqueObjects, function($uniqueObject) use ($object) { 
    return $uniqueObject->id == $object->id 
}); 

if (!$found) { 
    $uniqueObjects[] = $object; 
} 

$object è l'oggetto che stai cercando, ed è $uniqueObjects la matrice di oggetti che stai cercando per vedere se esiste. Basta associare uniqueObject e object su una proprietà di identificazione, ad esempio id.