0

如何从具有相同名称的对象数组中删除元素?在下面的情况下,我想删除元素 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"  
 } 
4

3 回答 3

2

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

当且仅当 (string) $elem1 === (string) $elem2 时,才认为两个元素相等。换句话说:当字符串表示相同时。将使用第一个元素。

于 2012-04-27T17:39:25.503 回答
2

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

代码:

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

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

于 2012-04-27T17:44:15.010 回答
0
$result = array_filter(
  $array,
  function ($item) use ($name) { return $item->name != $name; }
);

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

于 2012-04-27T17:37:19.380 回答