开发者

array intersect for object array php

I want开发者_如何学JAVA to know how to array_intersect for object array.


You can use array_uintersect in conjunction with spl_object_hash, see an example:

    array_uintersect($a, $b, function($a, $b) {
        return strcmp(spl_object_hash($a), spl_object_hash($b));
    });

where '$a' and '$b' are arrays of some objects that you want to intersect.


nice toString function is already implemented and is called serialize ;) so

array_map(
    'unserialize',
    array_intersect(
        array_map(
            'serialize',
            $obj1
        ), 
        array_map(
            'serialize', 
            $obj2
        )
    )
);

will do the work, example mentioned higher don't work 'cause array_intersect work's only with strings as someone mentioned too


array_intersect() returns an array containing all the values of array1 that are present in all the arguments.

Then what mean present in this context (exacly this function), i found on php.net my answer:

Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same.

Then you can't use it on array of objects if your objects not implements unique conversion to string.


Had a similar problem a few days ago, while these are answers are on the right path; I used them to work out the following:

From Artefacto's answer return $obj1 == $obj2 didn't really work, so I wrote a simple comparative function (basically gets the md5 of the serialised object and compares that):

function object_compare($obj1, $obj2){
  $md5 = function($obj){
    return md5(serialize($obj));
  };
  return strcmp($md5($obj1), $md5($obj2));
}

Then it’s jut a matter of calling array_uintersect with our comparative function to get the intersection:

# $array1 / $array2 are the array of objects we want to compare
return array_uintersect($array1, $array2, 'object_compare');

In my case, I had an unknown / dynamic array of objects, so I took it a step further so I don't have to declare array_uintersect($array1, $array2, ...) specifically - but just be able to pass in an array of arrays (of objects):

# $multiarray_of_objects is our array of arrays
$multiarray_of_objects[] = 'object_compare';
return call_user_func_array('array_uintersect', $multiarray_of_objects);

Just gotta remember to pass in the reference to our callback / comparative function as the last string in the array. Works like a charm!


The correct way to check whether two objects are equal is to use ==. Therefore:

array_uintersect($arr1, $arr2, function ($a1, $a2) { return $a1 == $a2; });


Just for completeness: Implement __toString() method in your object returning a unique value. For database entities this might be as easy as returning the fully qualified class name postfixed with the ID of the record. But it can also be arbitrarily complex by doing some hashing or even worse things.

In my opinion, it's the class's duty to serialize itself or create something unique to compare its objects by. Using anything outside of a class to serialize an object might result in strange behaviour (including comparing objects of different classes, which must never result in equality).


I use array_udiff to implement array_intersect for an object array.

 function diff($a, $b) {
 if($a === $b) {
     return 0;
 } else {
     return 1;}
 }

 $array_1 = array('a', 'b', 'c');    

 $array_2 = array('c', 'd','e');    

 $array = array_udiff($array_1, array_udiff($array_1, $array_2, 'diff'),'diff');

var_dump($array);
return array(1) { [2]=> string(1) "c" }

You can have your own diff function for any scheme.


The correct solution would be:

array_uintersect($arr1, $arr2, function ($a1, $a2) { return $a1 != $a2; });

Note the != in the callback function as opposed to the answer from @Artefacto. Based on the documentation of array_uintersect, the callback function has to return 0 (false) if array items are equal.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜