Remove duplicates from an array based on an object property?

I have an array of objects. I would like to remove duplicates based on the value of "name" in the object.

[0]=> object(stdClass)#337 (9) { ["term_id"]=> string(2) "23" ["name"]=> string(12) "Assasination" ["slug"]=> string(12) "assasination" } [1]=> object(stdClass)#44 (9) { ["term_id"]=> string(2) "14" ["name"]=> string(16) "Campaign Finance" ["slug"]=> string(16) "campaign-finance" } [2]=> object(stdClass)#298 (9) { ["term_id"]=> string(2) "15" ["name"]=> string(16) "Campaign Finance" ["slug"]=> string(49) "campaign-finance-good-government-political-reform" } 

So, in this case, how to remove the duplicate Campaign Financing object from the array. So, the whole object [2]?

I examined a number of issues related to duplicating a PHP array, but none of them dealt with objects and filtering immediately after one parameter.

+8
object php multidimensional-array duplicate-removal
source share
4 answers

Create a new array with existing keys and just name as value, use array_unique (note that it stores the keys).

Then remove everything that is not in a unique array from the source key.

Edit: Full example:

 class my_obj { public $term_id; public $name; public $slug; public function __construct($i, $n, $s) { $this->term_id = $i; $this->name = $n; $this->slug = $s; } } $objA = new my_obj(23, "Assasination", "assasination"); $objB = new my_obj(14, "Campaign Finance", "campaign-finance"); $objC = new my_obj(15, "Campaign Finance", "campaign-finance-good-government-political-reform"); $array = array($objA, $objB, $objC); echo "Original array:\n"; print_r($array); /** Answer Code begins here **/ // Build temporary array for array_unique $tmp = array(); foreach($array as $k => $v) $tmp[$k] = $v->name; // Find duplicates in temporary array $tmp = array_unique($tmp); // Remove the duplicates from original array foreach($array as $k => $v) { if (!array_key_exists($k, $tmp)) unset($array[$k]); } /** Answer Code ends here **/ echo "After removing duplicates\n"; print_r($array); 

Output:

 Original array: Array ( [0] => my_obj Object ( [term_id] => 23 [name] => Assasination [slug] => assasination ) [1] => my_obj Object ( [term_id] => 14 [name] => Campaign Finance [slug] => campaign-finance ) [2] => my_obj Object ( [term_id] => 15 [name] => Campaign Finance [slug] => campaign-finance-good-government-political-reform ) ) After removing duplicates Array ( [0] => my_obj Object ( [term_id] => 23 [name] => Assasination [slug] => assasination ) [1] => my_obj Object ( [term_id] => 14 [name] => Campaign Finance [slug] => campaign-finance ) ) 

An object with term_id 15 was deleted because it had the same name as term_id 14.

+11
source share

I was looking for a good answer to this question and could not find it, so I wrote my own, which will handle this case, and the case when you want to cancel the deletion based on several properties.

 $array = DeDupeArrayOfObjectsByProps($array, ['name']); 

Here's a common function:

 /** * Iterates over the array of objects and looks for matching property values. * If a match is found the later object is removed from the array, which is returned * @param array $objects The objects to iterate over * @param array $props Array of the properties to dedupe on. * If more than one property is specified then all properties must match for it to be deduped. * @return array */ public function DeDupeArrayOfObjectsByProps($objects, $props) { if (empty($objects) || empty($props)) return $objects; $results = array(); foreach ($objects as $object) { $matched = false; foreach ($results as $result) { $matchs = 0; foreach ($props as $prop) { if ($object->$prop == $result->$prop) $matchs++; } if ($matchs == count($props)) { $matched = true; break; } } if (!$matched) $results[] = $object; } return $results; } 

Here is the full use for your case:

 class my_obj { public $term_id; public $name; public $slug; public function __construct($i, $n, $s) { $this->term_id = $i; $this->name = $n; $this->slug = $s; } } $objA = new my_obj(23, "Assasination", "assasination"); $objB = new my_obj(14, "Campaign Finance", "campaign-finance"); $objC = new my_obj(15, "Campaign Finance", "campaign-finance-good-government-political-reform"); $array = array($objA, $objB, $objC); $array = DeDupeArrayOfObjectsByProps($array, ['name']); var_dump($array); 
+1
source share

I need the same ... Here's what I did (work with both an array and objects based on this post )

 function my_array_unique_by_subkey($array,$subkey){ $temp = array(); $unique = array_filter($array, function ($v) use (&$temp,$subkey) { if ( is_object($v) ) $v = (array)$v; if ( !array_key_exists($subkey,$v) ) return false; if ( in_array($v[$subkey], $temp) ) { return false; } else { array_push($temp, $v[$subkey]); return true; } }); return $unique; } 
+1
source share

A bit off topic, but closely related: the shortest way to deduplicate an array of objects only by their instance:

 /** * The array must NOT contain scalars. * * @param mixed[] $objects * @return mixed[] */ public static function arrayUniqueForObjects(array $objects): array { $deDuplicatedArray = []; foreach ($objects as $object) { $deDuplicatedArray[spl_object_hash($object)] = $object; } return array_values($deDuplicatedArray); } 
0
source share

All Articles