我想知道如何对对象数组使用array_intersect。
您可以将 array_uintersect 与 spl_object_hash 结合使用,以下是示例:
array_uintersect($a, $b, function($a, $b) {
return strcmp(spl_object_hash($a), spl_object_hash($b));
});
其中'$a'和'$b'是一些你想要求交集的对象数组。
<=>
运算符代替strcmp()
,代码如下:return spl_object_hash($a) <=> spl_object_hash($b);
- d-ph已经实现了优秀的toString函数,被称为serialize ;) 所以
array_map(
'unserialize',
array_intersect(
array_map(
'serialize',
$obj1
),
array_map(
'serialize',
$obj2
)
)
);
会做这个工作,之前提到的示例不起作用,因为array_intersect只能与字符串一起使用,正如有人也提到的那样。
几天前我遇到了类似的问题,尽管这些答案都有正确的方向;但是我使用它们来得出以下结论:
从Artefacto的答案中,return $obj1 == $obj2
并没有真正起作用,所以我编写了一个简单的比较函数(基本上是获取序列化对象的md5并进行比较):
function object_compare($obj1, $obj2){
$md5 = function($obj){
return md5(serialize($obj));
};
return strcmp($md5($obj1), $md5($obj2));
}
# $array1 / $array2 are the array of objects we want to compare
return array_uintersect($array1, $array2, 'object_compare');
在我的情况下,我有一个未知/动态对象数组,所以我采取了更进一步的措施,这样我就不必专门声明array_uintersect($array1, $array2, ...)
,只需能够传入一个数组 (由对象组成) 的数组:
# $multiarray_of_objects is our array of arrays
$multiarray_of_objects[] = 'object_compare';
return call_user_func_array('array_uintersect', $multiarray_of_objects);
只需记得将我们的回调/比较函数的引用作为数组中的最后一个字符串传递。像魔法一样起作用!
return array_uintersect($array1, $array2, 'self::object_compare');
应该可以工作,甚至可以使用 ClassName::object_compare
,但请记住它需要是一个公共的类函数。 - Atariarray_intersect()
函数返回一个数组,其中包含在所有参数中都存在的array1的所有值。
那么在这个上下文中,“present”是什么意思(确切地说是这个函数),我在php.net上找到了答案:
仅当(string)$ elem1 ===(string)$ elem2时,两个元素被视为相等。换句话说:当字符串表示相同时。
因此,如果您的对象没有实现唯一的字符串转换,则无法将其用于对象数组。
检查两个对象是否相等的正确方法是使用==
。 因此:
array_uintersect($arr1, $arr2, function ($a1, $a2) { return $a1 == $a2; });
__toString()
方法,返回一个唯一的值。对于数据库实体来说,这可能很容易,只需返回记录ID后缀的完全限定类名即可。但是,也可以通过进行一些哈希或更糟糕的操作来任意复杂化。我使用array_udiff来实现对象数组的array_intersect。
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" }
你可以为任何方案编写自己的差异函数。
正确的解决方案应该是:
array_uintersect($arr1, $arr2, function ($a1, $a2) { return $a1 != $a2; });
array_uintersect
的文档,如果数组项相等,则回调函数必须返回0(false)。