Home > Enterprise >  PHP Easier way to get unique in array of objects
PHP Easier way to get unique in array of objects

Time:04-05

I have been racking my head trying to think if there is a simpler method to grabbing the unique objects out of an array, but can't find any documentation or confirmation that anything exists that will do what I am asking.

I have an API returning the following:

Array
(
    [0] => stdClass Object
        (
            [Name] => Kory Kelly
            [PhoneNumber] => (555) 555-5555
            [EmailAddress] => [email protected]
        )

    [1] => stdClass Object
        (
            [Name] => Kory Kelly
            [PhoneNumber] => (555) 555-5555
            [EmailAddress] => [email protected]
        )

)

Now obviously I cannot use array_unique -- Since it checks actual values against array keys -- I have built a recursive function to tear apart the objects, rebuild as an array and do the checks manually during rebuild IE

if ( $arr['Name'] === $passed_arr['Name']
    && $arr['PhoneNumber'] === $passed_arr['PhoneNumber']
    && $arr['EmailAddress'] === $passed_arr['EmailAddress'] )

And that works .. But it seems a little long winded. Is there a built-in / more efficient approach to this? I feel like I am re-inventing the wheel with my current aproach.

CodePudding user response:

if you dont want to check the data type, then you can use array_unique() with the flag SORT_REGULAR for unique objects

$list = json_decode('[{
  "name": "Ahmed",
  "phone": "(555) 555-5555",
  "email" : "[email protected]"
},
{
  "name": "Ahmed",
  "phone": "(555) 555-5555",
  "email" : "[email protected]"
},
{
  "name": "Ahmed",
  "phone": "(555) 555-5555",
  "email" : "[email protected]"
}
]');

$uniqueList = array_unique($list, SORT_REGULAR );

the result should be

array(2) {
  [0]=>
  object(stdClass)#1047 (3) {
    ["name"]=>
    string(5) "Ahmed"
    ["phone"]=>
    string(14) "(555) 555-5555"
    ["email"]=>
    string(13) "[email protected]"
  }
  [2]=>
  object(stdClass)#1045 (3) {
    ["name"]=>
    string(5) "Ahmed"
    ["phone"]=>
    string(14) "(555) 555-5555"
    ["email"]=>
    string(14) "[email protected]"
  }
}

I hope it's useful

CodePudding user response:

If the JSON string of the objects is used as a key, this can also be implemented with a simple foreach loop.

$arr = [
  (object)['Name' => 'Kory Kelly', 'PhoneNumber' => '(555) 555-5555'],
  (object)['Name' => 'Kory Kelly', 'PhoneNumber' => '(555) 555-5555'],
  (object)['Name' => 'Kory Kelly', 'PhoneNumber' => '(555) 555-5555X'],  //different
];

foreach($arr as $key => $object){
  $arr[json_encode($object)] = $object;
  unset($arr[$key]);
}
$arr = array_values($arr);
var_dump($arr);

Try it yourself at 3v4l.org.

Compared to array_unique($arr, SORT_REGULAR ), this approach only becomes interesting if only certain keys are to be taken into account in the object comparison.

  • Related