I have an array of arrays of objects, and I'm trying to get the intersection of objects found in all of the inner arrays. My first attempt was to use the spread operator on the outer array and pass that to array_intersect
:
array_intersect(...array_values($test))
The function array_intersect
, however, uses a string-based comparison string representation:
Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same.
I can easily implement __toString
on most of my objects however one is already using this for another purpose and it isn't guaranteed to be unique. If I have to bite the bullet and refactor, I will, but I'm just seeing if there's another way to solve this cleanly.
The keys in the array do not matter, and both outer and inner arrays are not bounded.
(This is an aggregated search result from a bunch of components that is being AND'd together if anyone is wondering).
The basic gist is this:
class sample
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
// Comment this function out to see the error
public function __toString()
{
return spl_object_hash($this);
}
}
$obj1 = new sample('1');
$obj2 = new sample('2');
$obj3 = new sample('3');
$obj4 = new sample('4');
$obj5 = new sample('5');
$test = [
'a' => [
$obj1,
$obj2,
$obj5,
],
'b' => [
$obj2,
$obj3,
$obj5,
],
'c' => [
$obj2,
$obj3,
$obj5,
],
'd' => [
$obj2,
$obj4,
$obj5,
],
];
print_r(array_intersect(...array_values($test)));
Running that will produce exactly what I want:
Array
(
[1] => sample Object
(
[id] => 2
)
[2] => sample Object
(
[id] => 5
)
)
However, if you comment out the __toString()
method you'll see the exception Object of class sample could not be converted to string