I'm looking for a succinct way of comparing arrays of objects in PHP. I know I could just check for equal sized arrays and then loop through one array looking for each object in the second array, but I thought it would be nicer to use one or more of the array comparison functions.
I've tested a couple arrays of objects and the main problem I'm coming up against is that the array comparison functions insist on comparing elements as strings
, like this:
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);
outputs
Array
(
[1] => Foo Object
(
[pk] => 2
)
[2] => Foo Object
(
[pk] => 3
)
[3] => Foo Object
(
[pk] => 4
)
)
That's fine if the objects have __toString()
methods and if those __toString()
methods return a unique identifier and never ''
.
But what happens if that's not the case, say for an object like this:
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);
}
}
Is it possible to do array_uintersect($arr1,$arr2,$somecallback)
that forces the use of Foo::Equals()
? From what I can see the conversion to string
happens before the callback is called.
Any ideas how to get around this?
Yes, you can use array_uintersect
for this.
Some example 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'));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With