2011-09-11 59 views
2

我有对象的两个数组,循环和比较对象

他们是相同的,除了一个有多个项目,

,使他们看起来像

Array [arrayA] 
(
    [0] => stdClass Object 
     (
      [id] => 2 
      [name] => interest 1 
      [description] => interest one 
     ) 

    [1] => stdClass Object 
     (
      [id] => 4 
      [name] => interest 3 
      [description] => interest three 
     ) 

) 



Array [arrayB] 
(
    [0] => stdClass Object 
     (
      [id] => 1 
      [name] => all 
      [description] => everything 
     ) 

    [1] => stdClass Object 
     (
      [id] => 2 
      [name] => interest 1 
      [description] => interest one 
     ) 

    [2] => stdClass Object 
     (
      [id] => 4 
      [name] => interest 3 
      [description] => interest three 
     ) 

    [3] => stdClass Object 
     (
      [id] => 5 
      [name] => interest 4 
      [description] => interest four 
     ) 

) 

现在我想做的是,如果找到对象arrayA(可能比较ID?),则在arrayB之上循环,然后在arrayB上设置[checked] => true其他集合[checked] = false

这样做最简单的方法是什么?

我曾经想过做也许

foreach($arrayB as &$obj){ 
    $obj->checked = false; 
    foreach($arrayA as $obja){ 
     if($obja->id == $obj->id){ 
      $obj->checked = true; 
      break; 
     } 
     if($obja->id > $obj->id) //thanks to De3pTh0ught 
      break; 
    } 
} 

,但必须有一个更有效的方法?

回答

1

你可以添加一个检查来削减无用的迭代。如果您知道数组中的对象ID总是按递增顺序排列,那么可以包含以下条件:如果$ obja的ID大于$ obj的ID,则返回break $ arrayA的foreach循环,因为这意味着$ obj永远不会找到一场比赛。

0

这可以用这个可怕黑客来完成:

$p = print_r($arrayA, true); 
foreach($arrayB as &$o) $o->checked =substr_count($p, "[id] => {$o->id}\n") == 1; 
+0

小心解释这一点? (虽然我不认为我会在生产中使用这个...... waaay难以理解......) – Hailwood

+0

啊。我知道了。但哇... – Hailwood

+0

在第1行,我们得到一个字符串,就像你在你的问题中所拥有的一样。在第2行中,我们遍历$ arrayB中的id,并且为每一个我们编写一个像[[id] => 1'这样的子字符串,并检查$ p中是否有它的两个实例,我们将这个比较的结果赋给'$ o - > checked' –

0

经过一番思考如何低效substr_count可能是 - 认为它的内部实现的;(2行!)它不能很有效率 - 我想出了一个稍微不同的方法:

$b = print_r($arrayA, true); 
foreach($arrayB as &$o) 
    $o->checked = strpos($b, "[id] => {$o->id}" . PHP_EOL, 60) !== false;