How do I remove elements from an array of objects with the same name? In the case below, I want to remove elements 0 and 2 because the name is the same. I figured I could loop over every case but that seems wasteful.
array(1) {
[0]=> object(stdClass)#268 (3) {
["term_id"]=> string(3) "486"
["name"]=> string(4) "2012"
["count"]=> string(2) "40"
}
[1]=> object(stdClass)#271 (3) {
["term_id"]=> string(3) "488"
["name"]=> string(8) "One more"
["count"]=> string(2) "20"
}
[2]=> object(stdClass)#275 (3) {
["term_id"]=> string(3) "512"
["name"]=> string(8) "2012"
["count"]=> string(2) "50"
}
You can loop over the array, calculating how many times each name appears. Then you filter away those elements appearing more than once using array_filter. This will have an average runtime complexity of O(n)
(assuming O(1)
for arrays), compared to the naive O(n^2)
case.
Code:
$counter = array();
foreach($array as $val) {
$n = $val->name;
$counter[$n] = (!isset($counter[$n])) ? 1 : 2;
}
$result = array_filter(
$array,
function ($item) use ($counter) { return $counter[$item->name] == 1; }
);
For PHP versions before 5.3 you cannot use closures, so in that case, modify your code to this:
$counter = array();
foreach($array as $val) {
$n = $val->name;
$counter[$n] = (!isset($counter[$n])) ? 1 : 2;
}
function my_filter($item) {
global $counter;
return $counter[$item->name] == 1;
}
$result = array_filter(
$array,
'my_filter'
);
Note that this is only useful in reality for large arrays since there's some overhead involved. It may also be hard to read if you don't understand what's being done. For small arrays (a few hundred elements or so) I recommend you to use the naive quadratic-time loop approach.
$result = array_filter(
$array,
function ($item) use ($name) { return $item->name != $name; }
);
Note, that this is exactly this "loop over every case" you mentioned. There is no other solution, if you want to check every item.
If it are objects of classes you can modify, you could let the __toString()
method return the name
property and use array_unique()
:
Two elements are considered equal if and only if (string) $elem1 === (string) $elem2. In words: when the string representation is the same. The first element will be used.