2012-12-17 42 views
2

我的目标是在对象数组中找到重复对象,但仅限于特定的对象变量。根据特定键在对象数组中找到重复对象

而是使用两个的foreach循环像下面这样的,我正在寻找一个更好的(更优雅)的方式找到重复:

foreach ($data as $date) { 
     foreach ($data as $innerDate) { 
      if ($date->birthday == $innerDate->birthday && 
       $date->street == $innerDate->street && 
       $date->streetnr == $innerDate->streetnr && 
       $date->zipcode == $innerDate->zipcode && 
       $date->twinid == $innerDate->twinid && 
       $date !== $innerDate) { 
       // Duple 
     } 
    } 
} 

谢谢!


现在,我使用下面的代码,根据Tarilo的想法:

usort($data, function($obj_a, $obj_b){ 
     if ($obj_a->birthday == $obj_b->birthday && 
      $obj_a->street == $obj_b->street && 
      $obj_a->streetnr == $obj_b->streetnr && 
      $obj_a->zipcode == $obj_b->zipcode && 
      $obj_a->twinid == $obj_b->twinid) { 
      // Duple 
     } 
}); 

看起来比很多高2的foreach循环;-)

回答

2

您可以在阵列的第一,然后循环数组排序了排序。这样您只需将当前对象与下一个/上一个对象进行比较。你当前的算法是O(n^2)有效的,但是在排序之后它会是(排序+循环)=(O(log n)+ O(n))。其中n是数组中的对象的数量。

+0

好主意!我想我用'usort()'和一个回调函数来尝试这个函数,该函数根据变量对数组进行排序。希望这个比两个foreach循环更快。谢谢! – Tom

+0

我在上面的问题上发布了我的解决方案。谢谢你的想法。 – Tom

0

因为$的数据是一个数组,我们可以使用array_ *功能

试试这个,工作在我结束(PHP 5.2.0)。

if ($data != array_unique($data)) { 
    echo 'oops, this variable has one or more duplicate item(s)'; die; 
} 
+0

'array_unique'只适用于整个'$ data',但我只能比较它的一些变量。 – Tom

+0

对不起,我没有注意到你需要比较一些变量,不是全部。 – Husni

0

这一个给你一个数组与相似的项目。对于较大的数据集,应该更快:O(2n),并且字符串concat需要额外的成本,并计入结果组。由于hashmap只需要多一点内存。

$hashmap = array(); 
foreach ($data as $date) { 
    $hash = $date->zipcode.'-'.$date->street.'-'.$date->streetnr.'-'.$date->birthday.'-'.$date->twinid; 
    if (!array_key_exists($hash, $hashmap)) { 
     $hashmap[$hash] = array(); 
    } 
    $hashmap[$hash][] = $date; 
} 

foreach ($hashmap as $entry) { 
    if (count($entry) > 1) { 
     foreach ($entry as $date) { 
      // $date is a duplicate 
     } 
    } 
} 
相关问题