从包含相同名称的对象数组中删除元素


Remove elements from array of objects that contain the same name

如何从具有相同名称的对象数组中删除元素?在下面的例子中,我想删除元素 0 和 2,因为名称相同。我想我可以遍历每个案例,但这似乎很浪费。

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"  
 } 

您可以遍历数组,计算每个名称出现的次数。然后,使用 array_filter 过滤掉多次出现的元素。与朴素O(n^2)的情况相比,这将具有 O(n) 的平均运行时复杂度(假设数组O(1))。

法典:

$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; }
          );

对于 5.3 之前的 PHP 版本,您不能使用闭包,因此在这种情况下,请将您的代码修改为:

$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'
          );

请注意,这仅在实际中对大型数组有用,因为涉及一些开销。如果您不了解正在做什么,也可能很难阅读。对于小数组(几百个元素左右),我建议您使用朴素二次时间循环方法。

如果它是可以修改的类的对象,则可以让 __toString() 方法返回 name 属性并使用array_unique()

当且仅当(字符串)$elem 1 ===(字符串)$elem 2 时,两个元素被视为相等。简而言之:当字符串表示相同时。将使用第一个元素。

$result = array_filter(
  $array,
  function ($item) use ($name) { return $item->name != $name; }
);

请注意,这正是您提到的"遍历每个案例"。如果您想检查每个项目,没有其他解决方案。