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

时间:2012-04-27 17:33:52

标签: php arrays algorithm

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

3 个答案:

答案 0 :(得分:2)

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

  

当且仅当(字符串)$ elem1 ===(字符串)$ elem2时,两个元素被认为是相等的。用文字表示:当字符串表示相同时。将使用第一个元素。

答案 1 :(得分: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'
          );

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

答案 2 :(得分:0)

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

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