2010-12-03 22 views
5

Ich bin auf der Suche nach einer prägnanten Art und Weise Array von Objekten in PHP zu vergleichen. Ich weiß, ich könnte einfach nach Arrays gleicher Größe suchen und dann ein Array durchgehen, um nach jedem Objekt im zweiten Array zu suchen, aber ich dachte, es wäre besser, eine oder mehrere Array-Vergleichsfunktionen zu verwenden.Vergleiche Arrays von Objekten

ich ein paar Arrays von Objekten und das Hauptproblem gegen ich kommen getestet habe, ist, dass die Array-Vergleichsfunktionen als strings auf dem Vergleich von Elementen bestehen, wie folgt aus:

class Foo{ 
    public $pk=NULL; 
    function __construct($pk){ 
     $this->pk=$pk; 
    } 

    function __toString(){ 
     return (string)$this->pk;//even an integer must be cast or array_intersect fails 
    } 
} 

for($i=1;$i<7;$i++){ 
    $arr1[]=new Foo($i); 
} 
for($i=2;$i<5;$i++){ 
    $arr2[]=new Foo($i); 
} 

$int=array_intersect($arr1,$arr2); 
print_r($int); 

Ausgänge

Array 
(
[1] => Foo Object 
    (
     [pk] => 2 
    ) 

[2] => Foo Object 
    (
     [pk] => 3 
    ) 

[3] => Foo Object 
    (
     [pk] => 4 
    ) 

)

ist das in Ordnung, wenn die Objekte haben __toString() Methoden und wenn diejenigen __toString() Methoden geben einen eindeutigen Bezeichner zurück und niemals ''.

Aber was passiert, wenn das nicht der Fall ist, sagen für ein Objekt wie folgt aus:

class Bar{ 
    public $pk=NULL; 
    function __construct($pk){ 
     $this->pk=$pk; 
    } 

    function __toString(){ 
     return 'I like candy.';//same for all instances 
    } 

    function Equals(self $other){ 
     return ($this->pk==$other->pk); 
    } 

} 

Ist es möglich, array_uintersect($arr1,$arr2,$somecallback) zu tun, die die Verwendung von Foo::Equals() zwingt? Von dem, was ich sehen kann die Konvertierung in string passiert, bevor der Rückruf aufgerufen wird.

Irgendwelche Ideen, wie man das umgehen kann?

Antwort

7

Ja, Sie können hierfür array_uintersect verwenden.

Einige Beispiel-Code:

class Fos { 
    public $a = 0; 
    function __construct($a) { 
     $this->a = $a; 
    } 
    static function compare($a, $b) { 
     if ($a->a == $b->a) return 0; 
     if ($a->a > $b->a) return 1; 
     if ($a->a < $b->a) return -1; 
    } 
} 

$fos1 = array(); 
$fos2 = array(); 

for ($i = 1; $i < 10; $i++) { 
    $fos1[] = new Fos($i); 
} 

for ($i = 8; $i < 18; $i++) { 
    $fos2[] = new Fos($i); 
} 

$fosi = array_uintersect($fos1, $fos2, array('Fos','compare')); 
+0

Nice! Ich vergesse immer die 'array ('Fos', 'compare')' Notation um anzuzeigen, dass die Callback-Funktion zu einer Klasse gehört. Irgendeine Idee, wo diese Notation dokumentiert ist? Ich stoße nur gelegentlich darüber. – dnagirl

+1

@dnagirl: Siehe PHP Handbuch hier: http://de.php.net/manual/en/language.pseudo-types.php#language.types.callback –

+0

@Stefan Gehrig: vielen Dank! Manchmal ist es wirklich schwierig, Dinge zu finden, wenn man nicht weiß, wie sie heißen. – dnagirl

Verwandte Themen