Comparing arrays of objects

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?

Answers


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'));

Need Your Help

MVC - is it okay for business models to know each other?

php model-view-controller

Simple question: in MVC, is it okay for one model to interact with another? For example, with an Auth model...can it interact with the User model - or is there a better way to go about it?

Rails 3 model associations

ruby-on-rails ruby

I am making a simple BBS system with ruby on rails3.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.